当前线程没有与之关联的Dispatcher

时间:2017-01-20 08:52:44

标签: system.reactive

我创建了一个observable,并且我分别创建了订阅:

class CustomQuery {
    string Name;
    IObservable<int> Occurrences;
}

public IEnumerable<CustomQuery> GatherCustomQueryObservables()
{
    yield return new CustomQuery() {
        Name = "NameXXX",
        Occurrences = Observable.Create<int>(
            observer => 
            {
                int occurrences = this.webservice.GetOccurrences()
                observer.OnNext(occurrences);
                return System.Reactive.Disposables.Disposable.Empty;
            }
    );
}

另一方面,另一种方法是处理这些CustomQueries

public void CommitCustomQueryObservables(IEnumerable<CustomQuery> queries)
{
    foreach (CustomQuery query in queries)
    {
        query.Occurrences
            .Select(o => o)
            .SubscribeOn(System.Reactive.Concurrency.TaskPoolScheduler.Default)
            .ObserveOn(System.Reactive.Concurrency.DispatcherScheduler.Current)
            .Subscribe(
                occurrences =>
                {
                    string strOccurrences = occurrences > 0 ? occurrences.ToString() : "";
                    this.Label.Text = strOccurrences;
                }
            );
    }
}

尽管如此,我还是获得了System.InvalidOperationException例外:

  

当前线程没有与之关联的Dispatcher。

stacktrace的最后一行是

System.Reactive.Concurrency.DispatcherScheduler.get_Current(‌​).

我不太清楚如何处理它。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

对于Windows窗体,您需要使用ControlScheduler进行同步,而不是使用DispatcherScheduler。

现在您已经添加了System.Reactive.Windows.Forms包,只需使用[observable].ObserveOn([control])即可实现此功能。在你的例子中,这可能是:

public void CommitCustomQueryObservables(IEnumerable<CustomQuery> queries)
{
    foreach (CustomQuery query in queries)
    {
        query.Occurrences
            .Select(o => o)
            .SubscribeOn(System.Reactive.Concurrency.TaskPoolScheduler.Default)
            .ObserveOn(this.Label)
            .Subscribe(
                occurrences =>
                {
                    string strOccurrences = occurrences > 0 ? occurrences.ToString() : "";
                    this.Label.Text = strOccurrences;
                }
            );
    }
}