Albert Takács
Albert Takács

Reputation: 189

Reactive Extensions error when subscribing to an observable

I am getting a mysterious error on Windows Phone platform using the embedded Rx library.

Here is the call stack, which all I got, since they are coming from my users through error reports. I am not able to reproduce this error on emulator, and I did not get it on my dev phone.

An item with the same key has already been added. at Microsoft.Phone.Reactive.ObservableExtensions.b_3[TSource](Exception exception) at Microsoft.Phone.Reactive.AnonymousObserver1.Error(Exception exception) at Microsoft.Phone.Reactive.AbstractObserver1.OnError(Exception exception) at Microsoft.Phone.Reactive.AnonymousObservable1.AutoDetachObserver.Error(Exception exception) at Microsoft.Phone.Reactive.AbstractObserver1.OnError(Exception exception) at Microsoft.Phone.Reactive.Observable.<>c_DisplayClass17b`1.<>c_DisplayClass17d.<>c_DisplayClass181.b__178(Object _)

I am using Rx mostly for starting worker threads and subscribe to them on the UI thread like the following:

Observable.Start(() =>
{
    // do background work
    return result;
})
.ObserveOnDispatcher()
.Subscribe((result) =>
{
    // do UI work
});

The interesting thing is that I am using dictionaries, but I am checking for key existence all the time, so I can exclude them. My first thought is it could be an internal error. Could anyone help me out?

Upvotes: 1

Views: 528

Answers (1)

Chris Mantle
Chris Mantle

Reputation: 6683

The code you posted seems OK, and the exception is being caught by the Observable's error handler. Your mention of Dictionary objects makes it sound like a race condition somewhere, which may account for why you're finding it difficult to reproduce. Checking that a Dictionary doesn't already contain a key isn't enough when threading is involved. Two threads could check for the same key at the same time, and both may find that the key is not present. They'll both attempt to add to the dictionary, but only one will be successful, and the other is likely causing your exception. You must use locks around code that interacts with these dictionaries, or you can switch Dictionary for ConcurrentDictionary where you need to.

Upvotes: 2

Related Questions