Question

This code, called from the UI thread:

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;
    });

where ShowProgress does:

public void ShowProgress(Action<long> notify, Action terminate)
{
    this.Progress = Observable.Timer(ProgressInterval, ProgressInterval).Finally(terminate).Subscribe(notify);
}

blocks the UI thread completely, making it unresponsive.

If I insert .SubscribeOn(Scheduler.CurrentThread) before the Subscribe() call, it no longer blocks the UI thread. But then I get cross-thread exceptions, because the messages are not passed to the UI on the correct thread.

Is there a way to make that work so that I can get updates from the timer - leaving the UI responsive - that post back to the UI thread?

Was it helpful?

Solution

You need to add a call to ObserveOn(). If you use nuget package Rx-Xaml you can leverage ObserveOnDispatcher():

this.Progress = Observable.Interval(ProgressInterval)
                          .ObserveOnDispatcher()
                          .Finally(terminate)
                          .Subscribe(notify);

See my answer here to understand the difference between ObserveOn and SubscribeOn. Also, you don't supply the code for PerformStep() - I hope that it is fast and/or non-blocking.

I also replaced Timer with Interval as it saves you an argument.

Finally, presumably you are planning to dispose the subscription handle (this.Progress) when the job completes?

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top