[英]Catch exception in current thread when it's thrown in different thread
我的情況是:
從主線程開始,我啟動線程A。在主線程中,有一些while(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調用委托,則無法在while循環中剪切,因為它是其他線程。 事件也是一樣。
我該如何處理這個問題?
謝謝
實現此目的的最佳方法是使用任務並行庫。 如果使用TaskCreationOptions.LongRunning
啟動任務, 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/zh-cn/library/system.componentmodel.backgroundworker.runworkercompleted(v=vs.110).aspx 。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.