[英]Catch exception in current thread when it's thrown in different thread
My situation is: 我的情况是:
from main thread i start thread A. In main thread there some while(true) which run a lot of time. 从主线程开始,我启动线程A。在主线程中,有一些while(true)运行很多时间。 Inside of while is time consumption operations:
时间消耗内部是:
static void Main(string[] args)
{
new Thread(Go).Start();
while (true)
{
Thread.Sleep(1000);
}
}
private static void Go()
{
}
I wish generate exception in main thread if something go wrong in thread A 如果线程A中出现问题,我希望在主线程中生成异常
I read some articles, for example this one: catch exception that is thrown in different thread 我读了一些文章,例如这篇文章: 捕获在不同线程中引发的异常
and the only answer is: using shared variable ( one of answers ) 唯一的答案是:使用共享变量( 答案之一 )
So, solution: 因此,解决方案:
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;
}
is unacceptable, because i wish get exception ASAP. 是不可接受的,因为我希望尽快获得例外。 Not wait for loop cycling.
不等待循环循环。 For example, if i do cook cookies in while loop, i do not want wait for next cycle when i heat out: when heater is broken i wish in same moment generate exception in main thread.
例如,如果我确实在while循环中烹饪饼干,我不希望在加热时等待下一个周期:当加热器坏了时,我希望在同一时刻在主线程中生成异常。
Now, i can not pass delegates to thread: if i call delegate from thread A, is can not cut while loop, because it other thread. 现在,我无法将委托传递给线程:如果我从线程A调用委托,则无法在while循环中剪切,因为它是其他线程。 Same thing about events.
事件也是一样。
How can i handle this problem? 我该如何处理这个问题?
Thanks 谢谢
The best way to achieve this is using the Task Parallel Library. 实现此目的的最佳方法是使用任务并行库。 If you start your task with
TaskCreationOptions.LongRunning
, a new thread will be created for the execution of the body of the task. 如果使用
TaskCreationOptions.LongRunning
启动任务, TaskCreationOptions.LongRunning
创建一个新线程来执行任务主体。 You can then either access Task<T>.Result
or call Wait
from the main thread, and the exception (if any) will be propagated back to the thread. 然后,您可以访问
Task<T>.Result
或从主线程调用Wait
,并且该异常(如果有)将传播回该线程。 Use a CancellationTokenSource
to support cancellation of other operations that are executing concurrently with the Go
operation. 使用
CancellationTokenSource
支持取消与Go
操作同时执行的其他操作。
In the following example, calls to Thread.Sleep
are placeholders for application-specific time consuming operations. 在以下示例中,对
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;
}
}
As some of the related questions suggest, use a BackgroundWorker. 正如一些相关问题所建议的那样,请使用BackgroundWorker。 If the worker thread raises an exception, it gets passed to the main thread via the RunWorkerCompleted event.
如果辅助线程引发异常,它将通过RunWorkerCompleted事件传递给主线程。 See http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.runworkercompleted(v=vs.110).aspx .
请参阅http://msdn.microsoft.com/zh-cn/library/system.componentmodel.backgroundworker.runworkercompleted(v=vs.110).aspx 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.