Forum Xamarin.Forms
We are excited to announce that the Xamarin Forums are moving to the new Microsoft Q&A experience. Q&A is the home for technical questions and answers at across all products at Microsoft now including Xamarin!

We encourage you to head over to Microsoft Q&A for .NET for posting new questions and get involved today.

Frequent ApplicationMessageReceived += event from MQTTnet library causes Xamarin app to crash

Hi!

I've been working with Xamarin the past couple days, and this is my first big side project! I'm using the MQTTnet library to connect my mobile devices to a robotic system, to move the robot and also collect data.

The issue i'm having is with the ApplicationMessageReceived event from the MQTTnet:

client.ApplicationMessageReceived += (s, e) =>{ StatusLabel.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload) }

On the robot side it is publishing position values at about a 200ms interval over MQTT; after about 5 seconds of the app running the subscription event, it will lock and crash. This is not the case with my C# WPF and my .Net Core versions of a similar app. I can bump the interval to about 1 second interval, and it's somewhat stable, but not ideal for position readout.

Could someone give me pointers as to what might be happening, or the cause?

I have a task setup in my main program body:

        protected override void OnCreate()
        {
            base.OnCreate();
            LoadApplication(new App());

            //Task to run MQTT
        Task.Run(async () => { await App.RunAsync(); }).Wait();
        }

        static void Main(string[] args)
        {
            var app = new Program();
            global::Xamarin.Forms.Platform.Tizen.Forms.Init(app);
            Tizen.Wearable.CircularUI.Forms.Renderer.FormsCircularUI.Init();
            app.Run(args);
        }

And then in my App I have a RunAsync that does the connection and messaging, I've cut it short for readability:

        public static async Task RunAsync()
        {
                try
                {
                    // Event Handler to the ApplicationMessageRecevied event
                    client.ApplicationMessageReceived += (s, e) =>
                    {
                        StatusLabel.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                    };

                    client.Connected += async (s, e) =>
                    {
                        await client.SubscribeAsync(new TopicFilterBuilder().WithTopic(MQTTSubTopic).Build());
                        StatusLabel.Text = "Connected";
                    };

                    // Attempt a connection to the broker
                    try
                    {
                        await client.ConnectAsync(clientOptions);
                    }
                    catch
                    {
                        PositionData.Text = "Failed";
                    }
                }
                catch
                {
                    StatusLabel.Text = "Failed";
                }

        }

At this point, I'm open to try anything :smile:

I've tried moving the Task.Run() to the OnStart() event as well, and no difference in results. My .Net Core application does have a Thread.Sleep(Timeout.Infinite) directly after the Task.Run(), but adding that to this application just prevents it from launching.

Thanks!!

Best Answer

  • 0w8States0w8States Member ✭✭
    Accepted Answer

    I found that using the following to assign the label works well. My publisher is sending messages at 2ms intervals, and the watch is stable!

        Device.BeginInvokeOnMainThread(() => {
                                PositionData.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                            });
    
    

Answers

  • 0w8States0w8States Member ✭✭

    As a side note, I noticed that the application runs perfectly fine with a 10ms update frequency when I remove the Label text assignment.

    StatusLabel.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
    

    I've tested with both the M2MQTT and MQTTnet library, both seem to hang on this line. Is there a better way to set the Label text on the UI that will not cause the app to crash?

  • 0w8States0w8States Member ✭✭
    Accepted Answer

    I found that using the following to assign the label works well. My publisher is sending messages at 2ms intervals, and the watch is stable!

        Device.BeginInvokeOnMainThread(() => {
                                PositionData.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                            });
    
    
  • Kefi123Kefi123 Member ✭✭

    @0w8States said:
    I found that using the following to assign the label works well. My publisher is sending messages at 2ms intervals, and the watch is stable!

        Device.BeginInvokeOnMainThread(() => {
                                PositionData.Text = Encoding.UTF8.GetString(e.ApplicationMessage.Payload);
                            });
    
    

    Actually I am new in xamarin so can you share your code how to implement MqttNet in xamarin project?

Sign In or Register to comment.