开发者

Delegate Thread Must be allowed to complete

So I invoke a thread from managed code this way:

 Action<EFScmTechnologiesContext, long, long> updateReference = UpdateReferenceBaseline;
 IAsyncResult ar = updateReference.BeginInvoke(_context, baseline.Id, updatedBaseline.Id, null, null);

I have taken care to make sure that this class's destructor waits for the thread to complete. So for most normal cases, the thread is allowed to do its work before the process exists. However, I suspect there might be conditions (unhandled exceptions on other thread perhaps?) where the destructor is not called and the thread is terminated without being allowed it to complete.

What do I have to do . . . either in the delegate or the wrapper class, to make sure this thread is allowed to complete regardless of exceptions, aborts 开发者_运维百科or exits in another thread?

I read about UnhandledExceptionHandler(), but wasn't sure exactly what to do with it . . . I think by the time that handler is called my thread is already toast. I could also put a try/catch block in the delegate, but that would mean the thread is already interrupted from doing its current operations.

I also recognize that depending on the exception involved, the whole application environment might be toast . . . so even if I can catch/prevent the thread's termination . . . I probably should only allow it 30 seconds or so to try and complete its work and then let it die regardless . . .

I see lots of information on threads and exceptions in general, etc . . . but very little on the Exit process and the final moments of a process's life . . . if anyone has a pointer to a good description, please . . .


I think your way of doing this should be safe, unless your finalizer (also known as destructor) throws an exception itself.

But I would not recommend to you doing it this way. A better way would be to create a new thread for your method. Unless you change the Thread.ISBackground property, it is not created as a background thread, which means that the whole program will continue on running, until this thread stops:

var thread = new Thread(() => UpdateReferenceBaseline(_context, baseline.Id, updatedBaseline.Id, null, null));
thread.Start();


UnhandledExceptionHandler() and OnUnhandledException are not for the meek.

I think you would have to pass a reference to your IAsyncResult ar to classes, methods, or through an Interface accessor. That way in your exception handler you could:

void DoSomething(IPriorityProcess priorityProcess)
{
    try
    {
        // stuff here
    }
    catch (Exception ex)
    {
        if (!priorityProcess.IsCompleted)
        {
            // wait here or whatever
        }
    }
}


I would use:

try  
{ 
// Child thread code here
}   
catch ()  
{ // Catch child thread exceptions }  
finally  
{ ThreadIsComplete = true; }

in your child thread. Pass a reference to the ThreadIsComplete flag (or use a global with locking or whatever) to your child thread from your parent thread and check for the flag in your parent thread (as @IAbstract demonstrated) before proceeding.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜