此代码,从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);
}
完全阻止UI线程,使其无响应。
如果我在Subscribe()调用之前插入.SubscribeOn(Scheduler.CurrentThread),它将不再阻止UI线程。但后来我得到了跨线程异常,因为消息没有传递给正确线程上的UI。
有没有办法使这项工作能够让我从定时器获得更新 - 让UI响应 - 发回到UI线程?
答案 0 :(得分:2)
您需要添加对ObserveOn()
的通话。如果您使用nuget包Rx-Xaml,您可以利用ObserveOnDispatcher():
this.Progress = Observable.Interval(ProgressInterval)
.ObserveOnDispatcher()
.Finally(terminate)
.Subscribe(notify);
See my answer here to understand the difference between ObserveOn
and SubscribeOn
。此外,您不提供PerformStep()
的代码 - 我希望它快速和/或无阻塞。
我还将Timer
替换为Interval
,因为它可以为您节省一个参数。
最后,大概是你计划在作业完成时处理订阅句柄(this.Progress)?