【问题标题】:C# Finishing Background worker with custom errorC# 用自定义错误完成后台工作人员
【发布时间】:2018-06-02 20:47:16
【问题描述】:

我有一个后台工作人员(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 中的日志中。

我该怎么做?

【问题讨论】:

    标签: c# multithreading visual-studio-2008 .net-3.5 backgroundworker


    【解决方案1】:

    如果你想立即终止你的进程,你可以在那个时候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中解释了

    【讨论】:

      【解决方案2】:

      因为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 中的那个。或者,如果希望某人明确处理某事。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多