Я новичок в 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);
}
}
}
}
}
Можете ли вы быть более конкретным, пожалуйста, не в состоянии следовать, так и ваше выполнение прерывается методом 'ReceiveMessages'? – inan
Привет, нет, он продолжает находить, способен использовать ui и т. Д. Способ, которым он работает, заключается в том, что сообщение, полученное от концентратора IOT, обновляет текстовое поле, это датчик pir, прикрепленный к малине pi. Когда вы переходите на другую страницу, т.е. настройки и возвращаетесь на главную страницу, текстовое окно перестает обновляться, но сообщения и код продолжают работать. Если я запустил точку прерывания в цикле, она пробегает TimeText.Text = fine, но она просто не обновляется, но я все еще могу использовать остальную часть ui. –
ok, поэтому вы хотите попытаться переместить блок while while в метод async/await, чтобы он не блокировал ваш пользовательский интерфейс, вы попробовали это? – inan