gpt4 book ai didi

c# - 如何消除异步函数中循环报告进度的竞争条件?

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

我正在尝试根据 Task-based Asynchronous Pattern 报告异步函数的进度.

using System;
using System.Threading.Tasks;

namespace TestConsoleApplication1
{
class Program
{
static void Main()
{
Blah();
Console.ReadLine();
}

static async void Blah()
{
var ProgressReporter = new Progress<int>(i => Console.WriteLine(i + "%"));
await Foo(ProgressReporter);
}

static Task Foo(IProgress<int> onProgressPercentChanged)
{
return Task.Run(() =>
{
for (int i = 0; i < 1000; i++)
{
if (i % 100 == 0)
{
onProgressPercentChanged.Report(i / 100);
}
}
});
}
}
}

但是,作为 i不断更新,在打印之前,输出就搞砸了。示例输出:
1%
3%
0%
4%
5%
6%
8%
7%
9%
2%

我的信念是 IProgress 接口(interface)旨在通过等待任何 lambda 表达式或在进度更新时执行的方法来消除这种竞争条件。我是否遗漏了任何可以消除这种竞争条件的东西?

最佳答案

这是因为回调正在线程上运行。

为什么?

控制台应用程序。

根据 Progress类 MSDN 文档:

Any handler provided to the constructor or event handlers registered with the ProgressChanged event are invoked through a SynchronizationContext instance captured when the instance is constructed. If there is no current SynchronizationContext at the time of construction, the callbacks will be invoked on the ThreadPool.



本质上,您的回调不正常,因为没有 SynchronizationContext在控制台应用程序中......所以它们在 ThreadPool 线程上被触发。

在 Windows 应用程序中尝试它。这是完全相同代码的输出屏幕截图:

Sync example

关于c# - 如何消除异步函数中循环报告进度的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20930717/

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