Agr*_*rim 1 c# asynchronous async-await
我试图根据基于任务的异步模式报告异步函数的进度.
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接口旨在通过等待更新进度时要执行的任何lambda表达式或方法来消除此类竞争条件.我错过了任何可以消除这种竞争条件的东西吗?
这是因为回调正在一个线程上运行.
为什么?
控制台应用程序.
根据ProgressMSDN类文档:
向构造函数提供的任何处理程序或使用ProgressChanged事件注册的事件处理程序都是通过构造实例时捕获的SynchronizationContext实例调用的.如果在构造时没有当前的SynchronizationContext,则将在ThreadPool上调用回调.
从本质上讲,你的回调是不成功的,因为SynchronizationContext在Console应用程序中没有.所以它们在ThreadPool线程上被触发.
在Windows应用程序中尝试..这是完全相同代码的输出的屏幕截图:

| 归档时间: | 
 | 
| 查看次数: | 532 次 | 
| 最近记录: |