当当前线程在不同的线程中抛出时,捕获异常
本文关键字:线程 捕获异常 前线 | 更新日期: 2023-09-27 17:57:07
我的情况是:
从主线程我开始线程 A。在主线程中有一些时间(true)运行了很多时间。其中是耗时的操作:
static void Main(string[] args)
{
new Thread(Go).Start();
while (true)
{
Thread.Sleep(1000);
}
}
private static void Go()
{
}
如果线程 A 出现问题,我希望在主线程中生成异常
我读了一些文章,例如这篇文章:捕获在不同线程中抛出的异常
唯一的答案是:使用共享变量(答案之一)
因此,解决方案:
static void Main(string[] args)
{
new Thread(Go).Start();
while (true)
{
Thread.Sleep(1000);
if (_bad)
{
throw new Exception();
}
}
}
private static void Go()
{
Thread.Sleep(4000);
_bad = true;
}
是不可接受的,因为我希望尽快得到例外。不要等待循环循环。例如,如果我确实在 while 循环中煮饼干,我不想在加热时等待下一个循环:当加热器坏了时,我希望在同一时刻在主线程中生成异常。
现在,我无法将委托传递给线程:如果我从线程 A 调用委托,则不能在循环时切断,因为它是其他线程。事件也是如此。
我该如何处理这个问题?
谢谢
实现此目的的最佳方法是使用任务并行库。如果使用 TaskCreationOptions.LongRunning
启动任务,则会创建一个新线程来执行任务正文。然后,您可以从主线程访问Task<T>.Result
或调用Wait
,异常(如果有)将传播回线程。使用CancellationTokenSource
支持取消与Go
操作同时执行的其他操作。
在下面的示例中,对 Thread.Sleep
的调用是特定于应用程序的耗时操作的占位符。
private static CancellationTokenSource _cancellationTokenSource =
new CancellationTokenSource();
static void Main(string[] args)
{
Task longRunning = Task.Factory.StartNew(Go, TaskCreationOptions.LongRunning);
while (true)
{
// Pass _cancellationTokenSource.Token to worker items to support
// cancelling the operation(s) immediately if the long running
// operation throws an exception
Thread.Sleep(1000);
// this will throw an exception if the task faulted, or simply continue
// if the task is still running
longRunning.Wait(0);
}
}
private static void Go()
{
try
{
Thread.Sleep(4000);
throw new Exception("Oh noes!!");
}
catch
{
_cancellationTokenSource.Cancel();
throw;
}
}
正如一些相关问题所建议的那样,请使用 BackgroundWorker。 如果工作线程引发异常,它将通过 RunWorkerCompleted 事件传递到主线程。 请参阅 http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercomplete(v=vs.110).aspx。