簡體   English   中英

在不同線程中引發當前線程時捕獲異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM