简体   繁体   中英

Async Await operation blocking UI on return from another Frame

I am new to c# and UWP, This is an assignment and I am on a strict deadline so haven't had time to figure things out completely, so excuse the messy code.

I have the below code, which works by creating an AMQP connection and receiving messages from an Azure IOT Hub in a constant while loop.

There are properly allot of problems with it but the main one is that when I return from visiting another page the GUI stops updating the text fields.

Actually it does update them from OnNavigatedTo but the method Receive Messages stops updating them, however in the output window I can can see that debug.write is receiving the message, just not updating the text field.

I think I need to run the while loop on a separate thread and I dont think I have done that below, I have read into Task.Run etc and tried various ways but couldn't figure it out.

    public MainPage()
    {
        this.InitializeComponent();
        if (receivedStarted != 1)
            Receive();
    }

    private async void Receive()
    {
        await ReceiveMessages("1");
        await ReceiveMessages("0");
    }

    /// <summary>
    /// On Navigated to function from other pages
    /// </summary>
    /// <param name="e"></param>
    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        Counter.Text = parsedCounter;
        TimeText.Text = "The last activity was at " + parsedTime;
        Contact_1.Content = ContactAddPopUp.contact[0, 0];
        Contact_2.Content = ContactAddPopUp.contact[1, 0];
        Contact_3.Content = ContactAddPopUp.contact[2, 0];

        if (Settings.timeChanged == true)
        {
            if (DelayTimer != null)
            {
                DelayTimer.Cancel();
                Timer();
            }
        }
    }
    /// <summary>
    /// Receive messages from specified azure iothub on specified partition. The MessageManager parses the received message and displays it accordingly
    /// </summary>
    /// <param name="partition"></param>
    /// <returns></returns>
    public async Task ReceiveMessages(string partition)
    {         
        DateTime offset;
        offset = DateTime.UtcNow - TimeSpan.FromMinutes(1);
        String primaryKey = "fghkfwhihelfihefjw;ojwef";
        String sharedAccessPolicy = "iothubowner";
        //String hubName = "RaspberryPirSensor";
        String deviceName = "PIRSensor";
        String eventHubEntity = "iothub-ehub-raspberryp-70680-20f0331ccb";

        string port = "iakugfdkjhkjhaflhlkhalkfhse.servicebus.windows.net";
        Address address = new Address(port, 5671, sharedAccessPolicy, primaryKey, "/", "amqps");
        Connection connection = await Connection.Factory.CreateAsync(address);
        Session session = new Session(connection);
        string totalMilliseconds = ((long)(offset - new DateTime(StartOfEpoch, DateTimeKind.Utc)).TotalMilliseconds).ToString();
        Map filters = new Map();
        filters.Add(new Amqp.Types.Symbol("apache.org:selector-filter:string"),
                                    new DescribedValue(
                                        new Amqp.Types.Symbol("apache.org:selector-filter:string"),
                                        "amqp.annotation.x-opt-enqueuedtimeutc > " + totalMilliseconds + ""));
        ReceiverLink receiver = new ReceiverLink(session,
            "my-receiver",
            new global::Amqp.Framing.Source()
            {
                Address =
            eventHubEntity + "/ConsumerGroups/$Default/Partitions/" + partition,
                FilterSet = filters
            }, null);

        Amqp.Types.Symbol deviceIdKey = new Amqp.Types.Symbol("iothub-connection-device-id");
        string deviceId = deviceName;
        while (true)
        {
            if (timerCreated == false)
                Timer();
            receivedStarted = 1;
            Amqp.Message m = await receiver.ReceiveAsync(10000);
            if (m != null)
            {
                var id = m.MessageAnnotations.Map[deviceIdKey].ToString();
                if (id == deviceId)
                {
                    Data data = (Data)m.BodySection;
                    string msg = System.Text.Encoding.UTF8.GetString(data.Binary, 0, data.Binary.Length);
                    bool isValid = ValidateMessage(msg);

                    if (isValid)
                    {
                        receiver.Accept(m);
                        Counter.Text = parsedCounter;
                        Debug.Write("Receiving Message " + parsedCounter );
                        TimeText.Text = "The last activity was at " + parsedTime;

                        //Connection String
                        if (connection != null)
                            ConnectedTextBox.Text = "CONNECTED";
                        else
                            ConnectedTextBox.Text = "DISCONNECTED";

                        if (DelayTimer != null)
                            DelayTimer.Cancel();
                    }
                    else
                    {
                        receiver.Release(m);
                    }
                }
            }
        }
    }

I actually solved this by using - this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; - in the constructor of MainPage.

I was re-initializing the page every time I navigated to it, which I guess was causing it to loose sync with the awaited task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM