简体   繁体   English

异步等待操作阻止UI从另一个Frame返回时

[英]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. 我是C#和UWP的新手,这是一项任务,我的交稿时间很紧,所以还没有时间完全弄清楚问题,因此请原谅。

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. 我有以下代码,该代码通过创建AMQP连接并以恒定的while循环从Azure IOT集线器接收消息来工作。

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. 有适当的问题分配,但主要的问题是当我从访问另一页面返回时,GUI停止更新文本字段。

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. 实际上,它确实从OnNavigatedTo更新了它们,但是方法Receive Messages停止更新它们,但是在输出窗口中,我可以看到debug.write正在接收消息,只是不更新​​文本字段。

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. 我想我需要在单独的线程上运行while循环,但我认为下面没有做过,我已经读过Task.Run等,并尝试了各种方法,但无法弄清楚。

    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; 我实际上通过使用以下方法解决了这个问题-this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; - in the constructor of MainPage. -在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. 每次导航到该页面时,我都会重新初始化该页面,我认为这导致该页面与等待的任务失去同步。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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