我认为异步/等待的要点之一是,当任务完成时,在调用等待时在相同的上下文上运行延续,在我的例子中,这个上下文将是UI线程。
例如:
Debug.WriteLine("2: Thread ID: " + Thread.CurrentThread.ManagedThreadId);
await fs.ReadAsync(data, 0, (int)fs.Length);
Debug.WriteLine("3: Thread ID: " + Thread.CurrentThread.ManagedThreadId);我不期望这样做:
2: Thread ID: 10
3: Thread ID: 11怎么回事?为什么连续性的线程ID与UI线程不同?
根据this article^,我需要显式调用ConfigureAwait来更改延续上下文的行为!
发布于 2014-02-17 21:14:15
当您使用await时,默认情况下,await运算符将捕获当前的“上下文”,并使用该上下文恢复async方法。
这个“上下文”是SynchronizationContext.Current,除非它是null,在这种情况下,它是TaskScheduler.Current。(如果没有当前正在运行的任务,则TaskScheduler.Current与线程池任务调度程序TaskScheduler.Default相同)。
需要注意的是,SynchronizationContext或TaskScheduler并不一定意味着特定的线程。UI SynchronizationContext会将工作安排到UI线程;但是ASP.NET SynchronizationContext不会将工作安排到特定的线程。
我怀疑造成问题的原因是您调用async代码太早。当应用程序启动时,它只有一个普通的常规线程。该线程只有在执行类似Application.Run的操作时才会成为UI线程。
发布于 2014-02-17 20:29:51
await表达式将使用SynchronizationContext.Current值将控制流返回到其发生的线程。在这是null的情况下,它将默认为TaskScheduler.Current。当Task值完成时,实现仅依赖于此值来更改线程上下文。在本例中,await捕获的上下文没有绑定到UI线程
发布于 2020-12-30 08:11:19
默认情况下,Windows窗体在创建第一个控件时设置同步上下文。
所以你可以这样做:
[STAThread]
static void Main()
{
Application.SetHighDpiMode(HighDpiMode.SystemAware);
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var f = new Form1();
//var s=SynchronizationContext.Current;
//var s2=TaskScheduler.Current;
GetAsync();
Application.Run(f);
}
static async Task<bool> GetAsync()
{
MessageBox.Show($"thread id {Thread.CurrentThread.ManagedThreadId}");
bool flag = await Task.Factory.StartNew<bool>(() =>
{
Thread.Sleep(1000);
return true;
});
MessageBox.Show($"thread id {Thread.CurrentThread.ManagedThreadId}");
return flag;
}https://stackoverflow.com/questions/21838651
复制相似问题