C# 了解进度课程

C# 了解进度课程,c#,.net,multithreading,C#,.net,Multithreading,正如标题所说,我想了解课程Progress实际上在做什么。您可能会猜测以下实现具有相同的行为: class MyProgress<T> : IProgress<T> { private Action<T> _handler; public MyProgress(Action<T> handler) { _handler = handler; } public void Report(T v

正如标题所说,我想了解课程
Progress
实际上在做什么。您可能会猜测以下实现具有相同的行为:

class MyProgress<T> : IProgress<T>
{
    private Action<T> _handler;

    public MyProgress(Action<T> handler)
    {
        _handler = handler;
    }

    public void Report(T value)
    {
        _handler?.Invoke(value);
    }
}
class MyProgress:IProgress
{
私人行动;
公共MyProgress(操作处理程序)
{
_handler=handler;
}
公共作废报告(T值)
{
_处理程序?.Invoke(值);
}
}
在单线程程序中,我们不会观察到
Progress
MyProgress
之间的任何差异。但是,如果我们尝试在WPF应用程序中使用
MyProgress
类从不拥有WPF表单的线程更新进度条,就会得到
invalidoOperationException


因此,
Progress.Report
似乎在其所属线程中调用了处理程序。
Report
方法的正确实现是什么?

它在内部使用
SynchronizationContext
在SynchronizationContext线程上调用该方法,对于WPF,该线程将是UI线程

源代码:

应该避免InvalidOperationException。不太明显的要求是,必须从主UI线程上运行的代码调用其构造函数。这样,它就可以正确地复制SynchronizationContext.Current,从而允许它在UI线程上触发ProgressChanged事件并避免该异常。否则将执行与引擎盖下的Dispatcher.BeginInvoke()相同的操作。