xamarin / Xamarin.Forms

Xamarin.Forms is no longer supported. Migrate your apps to .NET MAUI.
https://aka.ms/xamarin-upgrade
Other
5.62k stars 1.87k forks source link

messagingcenter failure to unsubscribe #10921

Open vsfeedback opened 4 years ago

vsfeedback commented 4 years ago

This issue has been moved from a ticket on Developer Community.


Occasionally many symultainous (multiple threads) calls to MessagingCenter.Unsubscribe can result in an unsubscibe failing I have made a test application to prove this issue.

Android, Xamarin Forms versions 4.6.0.800

Output window

05-25 18:07:22.080 W/art ( 6827): JNI RegisterNativeMethods: attempt to register 0 native methods for crc643f46942d9dd1fff9. CollectionViewRenderer 05-25 18:07:22.443 I/art ( 6827): Enter while loop. Thread started: #8 Thread started: #9 Thread started: #10 Thread started: #11

....

[0:] Message received {9} [0:] Message received {9} Thread finished: #11 The thread 0xb has exited with code 0 (0x0). Thread finished: #9 The thread 0x9 has exited with code 0 (0x0). Thread finished: #10 The thread 0xa has exited with code 0 (0x0). Thread finished: #8 The thread 0x8 has exited with code 0 (0x0). [0:] Message received {9} Thread started: #112 Thread started: #113 Thread started: #114 Thread started: #115 Thread started: #116 Thread started: #117 [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} [0:] Message received {9} ..... (Recurring) .....


Original Comments

Visual Studio Feedback System on 5/26/2020, 03:29 AM:

We have directed your feedback to the appropriate engineering team for further evaluation. The team will review the feedback and notify you about the next steps.


Original Solutions

(no solutions)

samhouts commented 4 years ago

Note to triager: the test application is in the internal ticket.

jsuarezruiz commented 4 years ago

I couldn't find the reproduction sample, is it in the Developer Community ticket or somewhere else?

hartez commented 4 years ago

Here's a repro:

_10921 Repro.zip

Depending on the conditions and platforms on which you run it, you may see the behavior described above or it may simply crash.

The issue is that MessagingCenter is not thread-safe. We could make it thread-safe by moving the internal lookup from Dictionary to ConcurrentDictionary.

As a workaround, the MessageReceiver class in the repro could enforce thread safety:

internal class MessageReceiver
{
    public static object SyncObject = new object();

    internal MessageReceiver()
    {
        lock (SyncObject)
        {
            MessagingCenter.Subscribe<App>(this, "msg", sender => Debug.WriteLine("Message received {" + Thread.CurrentThread.ManagedThreadId.ToString() + "}"));
        }
    }

    internal void Unsubscribe()
    {
        lock (SyncObject)
        {
            MessagingCenter.Unsubscribe<App>(this, "msg");
        }
    }
}