c# - IProgress<T> 同步

标签 c# .net

我在 C# 中有以下内容

public static void Main()
{
    var result = Foo(new Progress<int>(i =>
        Console.WriteLine("Progress: " + i)));

    Console.WriteLine("Result: " + result);            
    Console.ReadLine();
}

static int Foo(IProgress<int> progress)
{
    for (int i = 0; i < 10; i++)
        progress.Report(i);

    return 1001;
}

Main 的一些输出是:

第一次运行:

Result: 1001
Progress: 4
Progress: 6
Progress: 7
Progress: 8
Progress: 9
Progress: 3
Progress: 0
Progress: 1
Progress: 5
Progress: 2

第二次运行:

Progress: 4
Progress: 5
Progress: 6
Progress: 7
Progress: 8
Progress: 9
Progress: 0
Progress: 1
Progress: 2
Result: 1001
Progress: 3

等...

每次运行,输出都是不同的。我如何才能同步这些方法,以便按照报告 0,1,...9 的顺序显示进度,然后是结果 1001。我希望输出如下所示:

Progress: 0
.
.
.
Progress: 9
Result: 1001

最佳答案

Progress<> 类使用 SynchronizationContext.Current 属性来 Post() 进度更新。这样做是为了确保 ProgressChanged 事件在程序的 UI 线程上触发,以便更新 UI 是安全的。需要安全地更新 ProgressBar.Value 属性。

控制台模式应用程序的问题在于它没有同步提供程序。不像 Winforms 或 WPF 应用程序。 Synchronization.Current 属性具有默认提供程序,其 Post() 方法在线程池线程上运行。在没有任何互锁的情况下,哪个 TP 线程首先报告其更新是完全不可预测的。也没有什么好的联锁方式。

只是不要在这里使用 Progress 类,没有意义。您在控制台模式应用程序中没有 UI 线程安全问题,Console 类已经是线程安全的。修复:

static int Foo()
{
    for (int i = 0; i < 10; i++)
        Console.WriteLine("Progress: {0}", i);

    return 1001;
}

关于c# - IProgress<T> 同步,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17982555/

相关文章:

c# - 如何在 IEnumerable<T> 上实现 ICollection<T>

c# - 一个语句中的 Linq 和 foreach 是否优于 2 个单独的显式语句?

c# - WorkflowDesigner - 如何指定表达式应该在 C# 中?

c# - 为什么我们不能序列化从接口(interface)派生的具体类?

C# IEnumerable 获取第一条记录

c# - myval = (someconditon) 吗?一些值 : myval get optimized to not set the value in case it's false

c# - 如何通过 Postman 发布到 Azure 函数(HTTP 触发器)?

.net - 如何使 vs2010 在文件末尾自动生成方法 stub

c# - 将 C# 代码转换为 Android

.net - 上下文自然语言资源,我从哪里开始?