BackgroundWorker dies unexpectedly

拥有回忆 提交于 2020-01-15 12:19:48

问题


I have the following code:

public Mainform()
{
...
        // scheduler
        scheduler.DoWork += new System.ComponentModel.DoWorkEventHandler(scheduler_DoWork);
        scheduler.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(scheduler_RunWorkerCompleted);
        scheduler.WorkerReportsProgress = false;
        scheduler.WorkerSupportsCancellation = true;
...

...

    scheduler_DoWork(this, null);
    scheduler.RunWorkerAsync(1000);

...
}    

void scheduler_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e)
    {
        if (e.Error != null)
        {
            scheduler_Enabled = false;
            CustomExceptionHandler eh = new CustomExceptionHandler();
            eh.HandleUnhandledException(e.Error, "scheduler");
        }
        if(scheduler_Enabled)  
        {
            scheduler.RunWorkerAsync(1000);
        }
    }


void scheduler_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
{

 try
 {            
    try
    {
      ...do some stuff
    }
    catch(MyException ex)
    {
       ThreadSafeShowError();
    }
    finally
    {}
    ...do more stuff
 }
 finally
 {
   if (e != null && e.Argument != null)
   {
    Thread.Sleep((int)e.Argument);
   }
 }
}

The backgroundworker thread died unexpectedly without any exception being thrown. I did not encounter this problem during development and it seems to be hard to reproduce. I suspected that maybe a cross thread exception was occurring when I am doing work in the scheduler_DoWork. I have tried to explicitly update the UI without checking if InvokeRequired and the thread continues to run without problems in a release build. How can this be? (Cross thread exception should occur) How can I determine what causes the thread to die? Any suggestions on how to figure out what is going wrong or how to debug this issue will be appreciated?


回答1:


The RunWorkerCompleted event might not be fired on the UI Thread. If it is not, then the thread will end and your scheduler object will be garbage collected, which will make it seem like it just quit with no error. See this post for more details. Here and here are SO posts about this.




回答2:


Your sample doesn't show enough code to determine what's going on but:

  • Maybe an exception is being thrown from ThreadSafeShowError? Why are you trying to show an error from the worker thread anyway - the conventional thing to do is to show e.Error if not null in the RunWorkerCompleted event handler.

To debug the issue try putting the following around all the code in your DoWork handler:

try
{
   // do work
   // log a trace statement here
}
catch(Exception ex)
{
   // log exception, e.g. with System.Diagnostics.Debug.Write
   throw;
}
finally
{
   // log a trace statement here
}



回答3:


You can do several things to increase the possibility of catching the exception:

  • Enable Managed Debugging Assistants for all exceptions in VS. To do that, go to Debug menu -> Exceptions..., and put a check mark next to "Managed Debugging Assistants" to enable all exceptions to be caught using debugger. Also, depending on the code you are executing, expand the CLR Exceptions node and select nodes of interest ("System" node, for example, will catch all exceptions from the System namespace in the debugger).

  • Obviously, put a try/catch block around your code, with some logging. You can also do something like this, if you are in real trouble:

  try
  {
      // do stuff
  }
  catch (Exception ex)
  {

#if DEBUG
      // break only in DEBUG builds
      System.Diagnostics.Debugger.Break();
#endif

      // log the exception and throw
      throw;
  }
  • Put a try/catch with logging around your Application.Run(...) code in the Main() method. Exceptions do propagate up there sometimes, and this can catch them (even if not coming from this specific part of your code).

  • Add an Application.ThreadException event handler in your Main() method, before calling Application.Run, like this:

Application.ThreadException +=
   new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);



回答4:


In Mainform, you never call scheduler.RunWorkerAsync, so your BackgroundWorker does not start at all.



来源:https://stackoverflow.com/questions/1682744/backgroundworker-dies-unexpectedly

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!