IProgress< T>同步 [英] IProgress<T> synchronization

查看:204
本文介绍了IProgress< T>同步的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在C#以下

 公共静态无效的主要()
{
    VAR的结果=美孚(新进展< INT>(I =>
        Console.WriteLine(进步+ I)));

    Console.WriteLine(结果:+结果);
    到Console.ReadLine();
}

静态INT美孚(IProgress< INT>进步)
{
    的for(int i = 0;我小于10;我++)
        progress.Report(ⅰ);

    返回1001;
}
 

主要的一些输出是:

首先运行:

 结果:1​​001
进展情况:4
进展情况:6
进展情况:7
进展:8
进展情况:9
进展情况:3
进展:0
进展:1
进展情况:5
进展情况:2
 

第二轮:

 进展:4
进展情况:5
进展情况:6
进展情况:7
进展:8
进展情况:9
进展:0
进展:1
进展情况:2
结果:1001
进展情况:3
 

等等...

对于每次运行,输出会有所不同。使进度显示在他们报道0,1的顺序,...我怎样才能同步这些方法9随后其结果是1001我要的输出是这样的:

 进展:0
。
。
。
进展情况:9
结果:1001
 

解决方案

进展&LT; T&GT; 类使用<一个href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.current.aspx"><$c$c>SynchronizationContext.Current属性<一个href="http://msdn.microsoft.com/en-us/library/system.threading.synchronizationcontext.post.aspx"><$c$c>Post()的最新进展。这样做是为了确保 ProgressChanged 一个程序,可以安全地更新UI的UI线程上的事件触发。既要安全地更新,比方说,<一个href="http://msdn.microsoft.com/en-us/library/system.windows.forms.progressbar.value.aspx"><$c$c>ProgressBar.Value属性。

与控制台模式的应用程序的问题是,它不具有同步提供。不喜欢一个WinForms或WPF应用程序。该 Synchronization.Current 属性有默认的提供者,其发布()方法运行在<一个href="http://msdn.microsoft.com/en-us/library/system.threading.threadpool.aspx"><$c$c>ThreadPool.在没有任何环环相扣,这种配置线程池线程得到汇报其更新第一个完全取消predictable。没有联锁无论是什么好办法。

只要不使用进展&LT; T&GT; 类在这里,没有一点。你不必在一个控制台模式的应用程序的UI线程安全的问题;在控制台类已经是线程安全的。修正:

 静态INT富()
{
    的for(int i = 0;我小于10;我++)
        Console.WriteLine(进展情况:{0},我);

    返回1001;
}
 

I have the following in 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;
}

Some outputs of Main are:

First run:

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

Second run:

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

etc...

For every run, the output is different. How can I synchronize these methods so that progress is displayed in the order they are reported 0,1,...9 followed by the result which is 1001. I want the output to be like this:

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

解决方案

The Progress<T> class uses the SynchronizationContext.Current property to Post() the progress update. This was done to ensure that the ProgressChanged event fires on the UI thread of a program so it is safe to update the UI. Necessary to safely update, say, the ProgressBar.Value property.

The problem with a console mode app is that it doesn't have a synchronization provider. Not like a Winforms or WPF app. The Synchronization.Current property has the default provider, its Post() method runs on the ThreadPool. Without any interlocking at all, which ThreadPool thread gets to report its update first is entirely unpredictable. There isn't any good way to interlock either.

Just don't use the Progress<T> class here, there is no point. You don't have a UI thread safety problem in a console mode app; the Console class is already thread-safe. Fix:

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

    return 1001;
}

这篇关于IProgress&LT; T&GT;同步的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆