gpt4 book ai didi

c# - 是否有必要用 Task.Run 包装将在非 GUI 线程中的延续?

转载 作者:太空宇宙 更新时间:2023-11-03 19:39:20 24 4
gpt4 key购买 nike

这个问题是为了学习目的。我肯定不会开发任何东西。

我有两个长时间运行的 CPU 绑定(bind)操作(JobAJobB)。两者都不与 GUI 交互。与在 await 表达式处立即完成的 Task.FromResult 不同,我的 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();
}

问题

在我看来,在下面的第二种情况下,用 Task.Run 包装 JobB 是不必要的,因为延续已经保证在非 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 行为有点棘手,所以我问这个问题是因为我想知道在发生异常时省略是否有风险。如果没有这种风险,我会删除这个问题。

最佳答案

my Task.Run(()=>JobA()).ConfigureAwait(false) will return control to the caller and causes the continuation to be executed in non-GUI thread (because of ConfigureAwait(false))

真的吗?你确定吗?

await 的一个有趣方面是,如果可能,它会同步运行。因此,如果任务在 await 检查时已经完成,则 await 将继续同步运行。在这种情况下,ConfigureAwait 无效。

值得注意的是,当您的不同计算机具有不同的 CPU 速度、可用内存或缓存行为时,就会发生这种情况。借助墨菲定律,您最终会遇到无法重现的生产问题,这总是很有趣。

因此,我从不依赖ConfigureAwait(false) 来保证任何代码都在线程池线程上运行。这就是 Task.Run 的用途。对于您发布的简单案例,您可以在 Task.Run 中完成一项又一项工作:await Task.Run(() => { JobA(); JobB(); }) ;

关于c# - 是否有必要用 Task.Run 包装将在非 GUI 线程中的延续?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56135164/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com