2016-10-15 1 views
0

Я новичок в C# и UWP. Это задание, и я нахожусь в строгом сроке, поэтому не успел полностью разобраться, так что извините грязный код.Async Await, блокирующий пользовательский интерфейс при возврате из другого кадра

У меня есть код ниже, который работает, создавая соединение AMQP и получая сообщения от концентратора Azure IOT в постоянном цикле while.

Есть должным образом проблемы с ним, но главным является то, что когда я возвращаюсь с посещения другой страницы, графический интерфейс останавливает обновление текстовых полей.

Фактически он обновляет их из OnNavigatedTo, но метод Receive Messages прекращает их обновлять, однако в окне вывода я могу видеть, что debug.write получает сообщение, просто не обновляя текстовое поле.

Мне кажется, мне нужно запустить цикл 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); 
        } 
       } 
      } 
     } 
    } 
+0

Можете ли вы быть более конкретным, пожалуйста, не в состоянии следовать, так и ваше выполнение прерывается методом 'ReceiveMessages'? – inan

+0

Привет, нет, он продолжает находить, способен использовать ui и т. Д. Способ, которым он работает, заключается в том, что сообщение, полученное от концентратора IOT, обновляет текстовое поле, это датчик pir, прикрепленный к малине pi. Когда вы переходите на другую страницу, т.е. настройки и возвращаетесь на главную страницу, текстовое окно перестает обновляться, но сообщения и код продолжают работать. Если я запустил точку прерывания в цикле, она пробегает TimeText.Text = fine, но она просто не обновляется, но я все еще могу использовать остальную часть ui. –

+0

ok, поэтому вы хотите попытаться переместить блок while while в метод async/await, чтобы он не блокировал ваш пользовательский интерфейс, вы попробовали это? – inan

ответ

0

Я на самом деле решить это с помощью - this.NavigationCacheMode = Windows.UI.Xaml.Navigation.NavigationCacheMode.Enabled; - в конструкторе MainPage.

Я заново инициализировал страницу каждый раз, когда я переходил к ней, что, по-моему, вызывало ее синхронность с ожидаемой задачей.

+0

Ницца вам удалось это решить – inan

+0

Спасибо за помощь в любом случае –

 Смежные вопросы

  • Нет связанных вопросов^_^