等待仍会阻塞当前UI线程

3

我试图使用以下代码在线程池中运行一些任务:

private async void button1_Click(object sender, EventArgs e)
{
   await test().ConfigureAwait(continueOnCapturedContext: false);
}
private Task test()
{
   Thread.Sleep(100000);
   return null;
}

这段代码应该在线程池中运行,然而当前的UI线程仍然被阻塞了。

有谁能帮忙看一下吗? 谢谢!


5
使用 async / await 并不意味着你的任务会在不同的线程上运行。 - dotnetom
1
但是,"continueOnCapturedContext: false" 会使它在线程池中运行吗? - HPPPY
不,continueOnCapturedContext: false 将确保 await 的继续不会使用 SynchronizationContext 被调用,而是在 ThreadPool 中完成。在你的问题中,Thread.Sleep() 只是在调用了 test() 方法的同一线程上执行,因此它将阻塞。代码将同步运行,直到它遇到第一个 await。因此,test() 是同步调用的,结果(一个空的 Task)被 "awaited"。 - deloreyk
你的Test()方法是synchronized同步的还是有异步调用async的呢? - Eldho
如果它是同步的,你可以尝试使用 await Task.Run(() =>Test()); - Eldho
显示剩余2条评论
2个回答

5

这段代码应该在线程池中运行。

不,这完全不正确。 async 不会在线程池线程上运行您的代码。

我建议您阅读我的async介绍,其中解释了async实际上做了什么,以及官方async FAQ,专门解决了线程池误解:

“async”关键字是否会将方法的调用排队到线程池中?创建一个新线程?发射火箭飞往火星吗?

不会。不会。也不会。


2

您应该使用Task.Delay方法。

private async void button1_Click(object sender, EventArgs e)
{
   await test();
}

private Task test()
{
    return Task.Delay(100000);
}

编辑:

相关问题/答案。

这是一个关于如何获取可等待的线程睡眠的问题/答案。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接