所以我用托管代码调用一个线程:
Action<EFScmTechnologiesContext, long, long> updateReference = UpdateReferenceBaseline;
IAsyncResult ar = updateReference.BeginInvoke(_context, baseline.Id, updatedBaseline.Id, null, null);
我已经注意确保这个类的析构函数等待线程完成。因此,对于大多数正常情况,允许线程在进程存在之前完成其工作。但是,我怀疑可能存在条件(其他线程上未处理的异常?),其中析构函数未被调用,并且线程终止而不允许它完成。
我该怎么做。 。 。在委托或包装类中,为了确保允许该线程完成而不管异常,在另一个线程中是中止还是退出?
我读过UnhandledExceptionHandler(),但不确定该如何处理它。 。 。我想当处理程序被调用时,我的线程已经是吐司。我也可以在委托中放置一个try / catch块,但这意味着线程已经因为当前的操作而被中断。
我也认识到,根据所涉及的异常,整个应用程序环境可能是吐司。 。 。即使我可以捕获/阻止线程的终止。 。 。我可能应该只允许它30秒左右尝试完成它的工作,然后让它死掉,无论如何。 。
我看到很多关于线程和异常的信息,等等。 。 。但退出过程和过程生命的最后时刻很少。 。 。如果有人指向一个好的描述,请。 。 。
答案 0 :(得分:3)
我认为你这样做的方式应该是安全的,除非你的终结器(也称为析构函数)本身抛出异常。
但我不建议你这样做。更好的方法是为您的方法创建一个新线程。除非你更改Thread.ISBackground property,否则它不会被创建为后台线程,这意味着整个程序将继续运行,直到此线程停止:
var thread = new Thread(() => UpdateReferenceBaseline(_context, baseline.Id, updatedBaseline.Id, null, null));
thread.Start();
答案 1 :(得分:0)
UnhandledExceptionHandler()
和OnUnhandledException
不适合温顺。
我认为您必须将对IAsyncResult ar
的引用传递给类,方法或通过接口访问器。在你的异常处理程序中你可以这样:
void DoSomething(IPriorityProcess priorityProcess)
{
try
{
// stuff here
}
catch (Exception ex)
{
if (!priorityProcess.IsCompleted)
{
// wait here or whatever
}
}
}
答案 2 :(得分:0)
我会用:
try
{
// Child thread code here
}
catch ()
{ // Catch child thread exceptions }
finally
{ ThreadIsComplete = true; }
在您的子线程中。从您的父线程向您的子线程传递对ThreadIsComplete标志的引用(或使用带有锁定或其他的全局),并在继续之前检查父线程中的标志(如@IAbstract所示)。