我有一个后台工作者(NET 3.5和Visual Studio 2008),它执行一些长时间的任务:
private void BWorker_DoWork(object sender, DoWorkEventArgs e)
{
string filename = GetFileName();
if (!string.IsNullOrEmpty(filename))
{
// Do long task
}
else
{
// Finish background worker with a custom error message
// in order to receive it in BWorker_RunWorkerCompleted and log it. Some kind of:
e.Error.Message = "my custom message error".
}
}
private void BWorker_ProcessChanged(object sender, ProgressChangedEventArgs e)
{
}
private void BWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Cancelled)
{
Logger.Process("Cancelled.");
}
else if (e.Error == null)
{
Logger.Process("Successfully completed");
}
else
{
// Log here my custom error
Logger.Error(string.Format("Completed with errors: {0}", e.Error.Message));
}
}
在长期任务中,我检查很多东西,所以如果一个失败,我想“强制”后台工作者根据情况完成自定义错误(如果有任何失败,则不需要继续执行后台工作程序)。然后,此错误将打印到BWorker_RunWorkerCompleted中的日志中。
我怎样才能做到这一点?
如果你想立即终止你的过程,你可以在这一点上throw
例外。确保异常未在调用层次结构的上方捕获。这将终止当前运行的进程,并将调用BWorker_RunWorkerCompleted
。然后,您将最终进入else
子句,您可以在其中记录消息。
throw new Exception("My custom Message");
应用于您的简单示例,它将如下所示:
if (!string.IsNullOrEmpty(filename))
{
// Do long task
}
else
{
// Finish background worker with a custom error message
// in order to receive it in BWorker_RunWorkerCompleted and log it.
throw new Exception("my custom message error");.
}
您还可以创建自己的自定义异常并将其抛出。在this article中解释了如何做到这一点
因为DoWork
方法在单独的后台/工作线程上运行,所以异常处理方式不同。抛出异常时,应该在RunWorkerCompleted
事件中处理它们。像这个例子:
private void BWorker_DoWork(object sender, DoWorkEventArgs e)
{
string filename = GetFileName();
if ( !string.IsNullOrEmpty( filename ) )
{
// Do long task
}
else
{
throw new InvalidOperationException( "my custom message error" );
}
}
private void BWorker_RunWorkerCompleted( object sender , RunWorkerCompletedEventArgs e )
{
if ( e.Error != null )
{
// my custom message error
Logger.Process( e.Error.ToString() );
}
else if ( e.Cancelled )
{
Logger.Process( "Cancelled." );
}
else
{
Logger.Process( "Success." );
}
}
最佳做法是抛出比非特定Exception
更清晰的类型异常。它根本不包含任何有用的信息。而且你必须使用捕获所有异常的catch块。
我一般使用InvalidOperationException
很多。您无需创建自定义异常。除非需要记录类型的特定信息,否则请使用.NET Framework中的那个。或者如果想要某人明确处理某事。