У меня в настоящее время частично синхронная (плохая) реализация связи UDP между моим Android-приложением и оборудованием, которое передает пакеты UDP.Приложение постоянно опрашивает оборудование на предмет информации о состоянии, которая затем используется для обновления пользовательского интерфейса.Приложение также имеет различные экраны, каждый из которых запрашивает (только когда пользователь переключает экраны, а не непрерывно) различный набор информации о конфигурации.Пользователь также может вносить изменения в конфигурации и загружать их в оборудование.Все это время обновления статуса продолжают выполняться в фоновом режиме.Я ищу решение, наиболее подходящее для моего сценария.
Вот что я сделал до сих пор (упрощен, чтобы сделать его более читабельным)
void InitializeUDP()
{
udpClient = new UdpClient(15001);
sender = default(IPEndPoint);
ThreadPool.QueueUserWorkItem(o => UDP_StatusCommunicator());
udpClient.EnableBroadcast = true;
udpClient.Client.ReceiveTimeout = 500;
}
void UDP_StatusCommunicator()
{
while (true)
{
if (update_flag)
{
try
{
sent_packet = FrameGenerator(frame_Queue[screen], true); //Creates UDP Packet
//CheckQuery(sent_packet);
udpClient.Send(sent_packet, sent_packet.Length,"192.168.4.255", 15000);
received_packet = udpClient.Receive(ref sender);
//CheckResponse(received_packet);
RunOnUiThread(() =>
{
Update_UI(received_packet);
});
}
catch (SocketException e)
{
Console.Writeline("Socket Timeout: " + e);
}
}
Thread.Sleep(update_delay);
}
}
void UDPReadWrite(int screen, bool reading)
{
SelectFunctionQueue(screen); //Select the frames according to the screen selected
//CheckQueue(frame_Queue);
for (int i = 0; i < frame_Queue.Length; i++)
{
try
{
sent_packet = FrameGenerator(frame_Queue[i], reading);
//CheckQuery(sent_packet);
udpClient.Send(sent_packet, sent_packet.Length, "192.168.4.255", 15000);
received_packet = udpClient.Receive(ref sender);
//CheckResponse(received_packet);
if (sent_packet[2] == received_packet[2]) //Verify correct packet received
{
Update_UI(received_packet);
}
else
{
i--; //retry
}
}
catch (SocketException e)
{
Console.WriteLine("Socket Timeout: " e);
i--;
}
}
}
}
void Switch_Screen(int new_screen)
{
update_flag = false;
UDPReadWrite(new_screen, true)
update_flag = true;
}
void User_Config_Write(int screen, byte[] data)
{
update_flag = false;
Update_Payload(data);
UDPReadWrite(screen, false)
update_flag = true;
}
Как вы, очевидно, заметили,это очень некорректная реализация.Я продолжаю сталкиваться с такими проблемами, как зависание пользовательского интерфейса, когда одно и то же использование сокетов выполняется двумя потоками одновременно, застревая во время ожидания пакетов.Я пытался использовать «async await», но я неправильно его реализую, что приводит к условиям гонки, а что нет.Любая помощь будет оценена