C# 需要可观察的计时器将消息传递给UI线程

C# 需要可观察的计时器将消息传递给UI线程,c#,system.reactive,C#,System.reactive,此代码从UI线程调用: Jobs.Current.ShowProgress(_ => { if (Jobs.Current.Duration == 0 && this.progressBarMarkJob.Value >= this.progressBarMarkJob.Maximum - this.progressBarMarkJob.Step / 2) { this.progressBarMarkJo

此代码从UI线程调用:

Jobs.Current.ShowProgress(_ =>
    {
        if (Jobs.Current.Duration == 0 && this.progressBarMarkJob.Value >= this.progressBarMarkJob.Maximum - this.progressBarMarkJob.Step / 2)
        {
            this.progressBarMarkJob.Step /= 2;
        }
        this.progressBarMarkJob.PerformStep();
    }, () =>
    {
        stopwatch.Stop();
        var elapsed = string.Format(stopwatch.Elapsed.TotalHours >= 1 ? @"{0:hh\:mm\:SS}" : @"{0:mm\:SS}", stopwatch.Elapsed);
        this.labelMarkTime.Text = string.Format("Elapsed{0:8}", elapsed);
        this.labelMarkTime.Visible = true;
        Jobs.Current.Duration = (uint)stopwatch.Elapsed.TotalSeconds;
        this.progressBarMarkJob.Value = this.progressBarMarkJob.Maximum;
    });
ShowProgress的作用是:

public void ShowProgress(Action<long> notify, Action terminate)
{
    this.Progress = Observable.Timer(ProgressInterval, ProgressInterval).Finally(terminate).Subscribe(notify);
}
public void ShowProgress(操作通知、操作终止)
{
this.Progress=Observable.Timer(ProgressInterval,ProgressInterval)。Finally(终止)。Subscribe(通知);
}
完全阻止UI线程,使其无响应

如果在Subscribe()调用之前插入.SubscribeOn(Scheduler.CurrentThread),它将不再阻止UI线程。但是我得到了跨线程异常,因为消息没有传递到正确线程上的UI


有没有一种方法可以让它正常工作,这样我就可以从计时器中获得更新—让UI保持响应—并将其发回UI线程?

您需要添加对
ObserveOn()
的调用。如果使用nuget软件包Rx Xaml,则可以利用ObserveOnDispatcher():

。另外,您没有为
PerformStep()
提供代码-我希望它是快速和/或无阻塞的

我还用
Interval
替换了
Timer
,因为它为您保存了一个参数


最后,假设您计划在作业完成时处理订阅句柄(this.Progress)?

显然,您在与UI不同的线程上订阅,然后通过其调度程序调用以将进度条更新到UI线程上。你有你需要的所有信息,不知道为什么你有这个问题。Background=>UI call martialing历史悠久,这里有很多关于这个主题的问题。谢谢你,我会很感激的,但我没有找到这些答案,即使经过很多搜索,我也不清楚。来点提示怎么样?特别是,我看到文档告诉我使用Dispatcher,但在编写代码时,编译器会在我尝试该选项时标记一个错误。谢谢,@James,非常有用,特别是SubscribeOn和ObserveOn之间的对比。我也喜欢间隔使用的改进。PerformStep的代码由ProgressBar提供;是的,当作业完成时,我会在别处处理计时器。但是,现在我得到了错误:无法加载文件或程序集'System.Reactive.Core,Version=2.0.20823.0,Culture=neutral,PublicKeyToken=f300afd708cefcd3'或其依赖项之一。定位的程序集清单定义与程序集引用不匹配。(HRESULT的异常:0x8013100)听起来像是在混合Rx DLL的不兼容版本。解决方案中的其他地方是否对Reactive.Core进行了特定于版本的引用?最新版本是2.2。是的,我引用的是一个过时版本的Reactive.Windows.Forms。固定的!再次感谢。现在都在工作。
this.Progress = Observable.Interval(ProgressInterval)
                          .ObserveOnDispatcher()
                          .Finally(terminate)
                          .Subscribe(notify);