此代码是从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线程,使其没有响应。
如果我在订阅()调用之前插入.SubscribeOn(Scheduler.CurrentThread),它将不再阻塞UI线程。但是,我得到了跨线程异常,因为消息没有在正确的线程上传递给UI。
是否有一种方法可以让我从计时器那里得到更新--让UI响应--回到UI线程?
发布于 2014-01-27 22:34:13
您需要向ObserveOn()添加一个调用。如果使用nuget包Rx,可以利用ObserveOnDispatcher():
this.Progress = Observable.Interval(ProgressInterval)
.ObserveOnDispatcher()
.Finally(terminate)
.Subscribe(notify);SubscribeOn。另外,您也没有为PerformStep()提供代码--我希望它是快速和/或非阻塞的。
我还将Timer替换为Interval,因为它为您节省了一个参数。
最后,假设您计划在作业完成时释放订阅句柄(this.Progress)?
https://stackoverflow.com/questions/21390625
复制相似问题