Jordi
Jordi

Reputation: 23197

The current thread has no Dispatcher associated with it

I'm creating an observable and I'm creating the subscription separately:

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

By other hand, there's another method deals with these 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;
                }
            );
    }
}

Nevertheless, I'm getting a System.InvalidOperationException exception:

The current thread has no Dispatcher associated with it.

The last line of the stacktrace is at

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

I don't quite figure out how to handle it.

Any ideas?

Upvotes: 0

Views: 1262

Answers (1)

ibebbs
ibebbs

Reputation: 1993

For Windows Forms you need to use the ControlScheduler for synchronization, not the DispatcherScheduler.

Now you've added the System.Reactive.Windows.Forms package this can be achieved by simply using [observable].ObserveOn([control]); in your example this could be:

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

Upvotes: 3

Related Questions