How do I change the code to receive messages asynchronously? The application is written in C# WinForms
My application sends messages asynchronously, does not receive synchronously. What should I change so that it receives asynchronously? `
private void ReceiveUDPMessage()
{
while (true)
{
try
{
Int32 port = Int32.Parse(LocalPortTextBox.Text);
IPAddress ip = IPAddress.Parse(LocalIPTextBox.Text.Trim());
IPEndPoint remoteIPEndPoint = new IPEndPoint(ip, port);
byte[] content = udpClient.Receive(ref remoteIPEndPoint);
if (content.Length > 0)
{
string message = Encoding.ASCII.GetString(content);
// Обработка полученных сообщений и обновление состояния робота
HandleReceivedMessage(message);
}
}
catch
{
string errmessage = "RemoteHost lost";
this.Invoke(myDelegate, new object[] { errmessage });
}
}
}
private void HandleReceivedMessage(string message)
{
switch (message)
{
case "MoveToSector1":
UpdateRobotState(RobotState.MovingToSector1);
break;
}
}`
If you want to make a method for async-await, you'll have to do the following:
Task
instead of void
; return Task<TResult>
instead of TResult
. The only exception to this are event handlers. They return void, even though they are declared async.await Task<TResult>
is TResult
.It is custom to add Async to the name of the method. This way you can have both a sync and an async method: File.Write
and File.WriteAsync
Until now, you were using
public byte[] Receive (ref System.Net.IPEndPoint? remoteEP);
However the async method, doesn't have a parameter that contains the IpEndPoint
public Task<System.Net.Sockets.UdpReceiveResult> ReceiveAsync ();
The Received data and the RemoteEndPoint are in the UpdReceiveResult. So after await you'll have to fetch them.
private async Task ReceiveUDPMessageAsync()
{
while (true)
{
try
{
// do some preparations before you call the async method
Int32 port = Int32.Parse(LocalPortTextBox.Text);
IPAddress ip = IPAddress.Parse(LocalIPTextBox.Text.Trim());
IPEndPoint remoteIPEndPoint = new IPEndPoint(ip, port);
udpClient.Connect(ipEndPoint);
// call the async method.
// To show what happens I write it with intermediate steps
Task<UdpReceiveResult> taskReceive = udpClient.ReceiveAsync();
// Because I didn't await yet, if needed I could do something else
// while the udpClient is receiving, for example:
DoSomethingElse();
// Now you can't continue without the result of the async Receive
// action,await for it:
UdpReceiveResult receiveResult = await taskReceive;
remoteIPEndPoint = receiveResult.RemoteEndPoint;
byte[] content = receiveResult.Buffer;
if (content.Length > 0)
{
string message = Encoding.ASCII.GetString(content);
// Обработка полученных сообщений и обновление состояния робота
HandleReceivedMessage(message);
}
}
catch
{
string errmessage = "RemoteHost lost";
this.Invoke(myDelegate, new object[] { errmessage });
}
}
}
Of course, if you've got nothing to do but await, you can combine these statements:
UdpReceiveResult receiveResult = await udpClient.ReceiveAsync();
byte[] content = receiveResult.Buffer;
etc.