Skip to content
This repository has been archived by the owner on Sep 20, 2021. It is now read-only.

Messenger - Sporadic exception when sending messages because of racing condition #65

Open
small-horse opened this issue Mar 21, 2019 · 0 comments

Comments

@small-horse
Copy link

Inside the Messenger.cs class you can run into this exception
System.Collections.Generic.KeyNotFoundException
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at GalaSoft.MvvmLight.Messaging.Messenger.SendToTargetOrType[TMessage](TMessage message, Type messageTargetType, Object token) in D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (PCL)\Messaging\Messenger.cs:Zeile 689.
at GalaSoft.MvvmLight.Messaging.Messenger.Send[TMessage](TMessage message) in D:\GalaSoft\mydotnet\MVVMLight\source\GalaSoft.MvvmLight\GalaSoft.MvvmLight (PCL)\Messaging\Messenger.cs:Zeile 295.

The reason is, that the Cleanup() method can be called and remove the key from the _recipientsOfSubclassesAction list while it is being iterated over. The list is only locked for the actual sending of messages, but not for the duration of the iteration.

At the beginning of the method you can find the following code

// Clone to protect from people registering in a "receive message" method
// Correction Messaging BL0008.002
var listClone =_recipientsOfSubclassesAction.Keys.Take(_recipientsOfSubclassesAction.Count()).ToList();

and this is the type list we iterate over when sending messages

However, since the Cleanup() can run during this iteration, it is not guaranteed that the key exists when later calling

 lock (_recipientsOfSubclassesAction)
                        {
                            list = _recipientsOfSubclassesAction[type].Take(_recipientsOfSubclassesAction[type].Count()).ToList();
                        }

One solution would be to check the existence of the key again before sending the message.

 lock (_recipientsOfSubclassesAction)
{
     if(_recipientsOfSubclassesAction.ContainsKey(type))
     {
          list = _recipientsOfSubclassesAction[type].Take(_recipientsOfSubclassesAction[type].Count()).ToList();
     }
}
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant