From 1030a20fac73e5e9f641ed81e016b80a1a9bd36d Mon Sep 17 00:00:00 2001
From: Stefan Steinhilber <stefan.steinhilber@bizerba.com>
Date: Mon, 21 Jun 2021 11:32:38 +0200
Subject: [PATCH] Fix register/unregister issues of WeakReferenceMessenger

---
 .../Messaging/WeakReferenceMessenger.cs       |  4 +++-
 .../UnitTests.Shared/Mvvm/Test_Messenger.cs   | 23 +++++++++++++++++++
 2 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/Microsoft.Toolkit.Mvvm/Messaging/WeakReferenceMessenger.cs b/Microsoft.Toolkit.Mvvm/Messaging/WeakReferenceMessenger.cs
index 3f79f23..19e1449 100644
--- a/Microsoft.Toolkit.Mvvm/Messaging/WeakReferenceMessenger.cs
+++ b/Microsoft.Toolkit.Mvvm/Messaging/WeakReferenceMessenger.cs
@@ -406,6 +406,8 @@ public bool MoveNext()
 
                     while (node is not null)
                     {
+                        LinkedListNode<WeakReference<TKey>>? nextNode = node.Next;
+
                         // Get the key and value for the current node
                         if (node.Value.TryGetTarget(out TKey? target) &&
                             this.owner.table.TryGetValue(target!, out TValue? value))
@@ -421,7 +423,7 @@ public bool MoveNext()
                             this.owner.keys.Remove(node);
                         }
 
-                        node = node.Next;
+                        node = nextNode;
                     }
 
                     return false;
diff --git a/UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.cs b/UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.cs
index e5b4fd0..6b9009e 100644
--- a/UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.cs
+++ b/UnitTests/UnitTests.Shared/Mvvm/Test_Messenger.cs
@@ -511,6 +511,29 @@ void Test()
             messenger.Cleanup();
         }
 
+        [TestCategory("Mvvm")]
+        [TestMethod]
+        [DataRow(typeof(StrongReferenceMessenger))]
+        [DataRow(typeof(WeakReferenceMessenger))]
+        public void Test_Messenger_RegisterMultiple_UnregisterSingle(Type type)
+        {
+            var messenger = (IMessenger)Activator.CreateInstance(type);
+
+            var recipient1 = new object();
+            var recipient2 = new object();
+
+            int handlerCalledCount = 0;
+
+            messenger.Register<object, MessageA>(recipient1, (r, m) => { handlerCalledCount++; });
+            messenger.Register<object, MessageA>(recipient2, (r, m) => { handlerCalledCount++; });
+
+            messenger.UnregisterAll(recipient2);
+
+            messenger.Send(new MessageA());
+
+            Assert.AreEqual(1, handlerCalledCount);
+        }
+
         public sealed class RecipientWithNoMessages
         {
             public int Number { get; set; }