首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >需要可观察到的计时器将消息传递给UI线程。

需要可观察到的计时器将消息传递给UI线程。
EN

Stack Overflow用户
提问于 2014-01-27 20:09:11
回答 1查看 1.1K关注 0票数 1

此代码是从UI线程调用的:

代码语言:javascript
复制
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这样做的地方:

代码语言:javascript
复制
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线程?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-27 22:34:13

您需要向ObserveOn()添加一个调用。如果使用nuget包Rx,可以利用ObserveOnDispatcher():

代码语言:javascript
复制
this.Progress = Observable.Interval(ProgressInterval)
                          .ObserveOnDispatcher()
                          .Finally(terminate)
                          .Subscribe(notify);

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

我还将Timer替换为Interval,因为它为您节省了一个参数。

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

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21390625

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档