这个问题是出于学习目的。我不确定要开发什么。
我有两个长时间运行的CPU绑定操作(JobA
和JobB
)。两者都不与GUI交互。与Task.FromResult
立即在await表达式中完成不同,我的Task.Run(()=>JobA()).ConfigureAwait(false)
将控制权返回给调用者,并导致继续在非GUI线程中执行(由于ConfigureAwait(false)
)。>
static void JobA()
{
for (int i = 0; i < int.MaxValue; i++) ;
}
static void JobB()
{
for (int i = 0; i < int.MaxValue; i++) ;
}
private static async Task Async()
{
await Task.Run(()=>JobA()).ConfigureAwait(false);
JobB();
//await Task.Run(() => JobB());
}
private async void Button_Click(object sender, RoutedEventArgs e)
{
await Async();
}
根据我的理解,不必像下面第二种情况那样用JobB
来包装Task.Run
,因为已经保证了延续可以在非GUI线程中运行。
private static async Task Async()
{
await Task.Run(()=>JobA()).ConfigureAwait(false);
JobB();
}
private static async Task Async()
{
await Task.Run(()=>JobA()).ConfigureAwait(false);
await Task.Run(() => JobB());
}
Exception
在异步中的行为有些棘手,所以我问这个问题,因为我想知道发生异常时进行选区是否有风险。如果没有这种风险,我将删除此问题。
答案 0 :(得分:5)
我的Task.Run(()=> JobA())。ConfigureAwait(false)将控制权返回给调用者并导致继续在非GUI线程中执行(因为ConfigureAwait(false))
真的吗?您确定吗?
await
的一个有趣方面是,如果可能的话,它的行为是同步的。因此,如果在await
检查任务时任务已经完成,则await
将继续同步运行。在这种情况下,ConfigureAwait
无效。
值得注意的是,当您使用不同的计算机使用不同的CPU速度,可用内存或缓存行为时,可能会发生这种情况。掌握了墨菲定律,您最终遇到了无法复制的生产问题,这总是很有趣。
所以,我从不依靠ConfigureAwait(false)
来确保任何代码都在线程池线程上运行。这就是Task.Run
的目的。对于您发布的简单案例,您可以在Task.Run
内完成一项工作:await Task.Run(() => { JobA(); JobB(); });