【发布时间】:2015-12-06 08:50:49
【问题描述】:
我在编写以下程序时搞砸了 c# 的 await/async:
using System;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
Test();
while (true) { }
}
static async void Test()
{
var t = Task.Run(()=> Thread.Sleep(1000));
await t;
throw new Exception("This exception happens in a worker thread");
}
}
当我运行这个程序时,我可以在 Visual Studio 的线程窗口中清楚地看到异常发生在 Worker Thread,而不是 Main Thread,这让我相信当我等待任务时,我的方法可以由另一个线程完成。
但是,当我打开一个新的 Windows 窗体应用程序并添加以下事件处理程序时:
async void button1_Click(object sender, EventArgs e)
{
var task = Task.Run(() => Thread.Sleep(1000));
await task;
button1.Text = "I'm in the main thread!"; //this works
}
这可行,所以我注意到在控制台应用程序中,我的 Test 函数由工作线程恢复,而在 Windows 窗体应用程序中,它总是由主线程恢复。
这是为什么?靠谱吗?
【问题讨论】:
-
当您等待任务时,任务中抛出的任何异常都会在等待恢复的上下文中重新抛出(即窗口程序中的 UI 线程)。这是可靠的。
-
是的,我也在某处读过,但是在控制台应用程序中,如果我在 throw new Exception 语句中设置断点并检查线程窗口,我会看到一个工作线程作为当前线程
标签: c# asynchronous async-await