2

I'm working on an interface in .NET Core for an old lighting console and am currently implementing the packets. The basic idea of this interface/API is the following: the client sends its packets on one UDP port and the console is responding with an error code. The console sends its packets through another UDP port.

So as I designed the the API, I just used an Action<ErrorCode> as my callback function. But this method is not very practical when dealing with more than one packet at a time.

My UdpClient has an event raised when receiving packets, but the console doesn't return more than the 4 byte error-code.

So I've tried it using a SemaphoreSlim.

My idea is to let the sender wait until the event and release the semaphore. The question is basically wether this is the fastest and 'cleanest' way of dealing with this problem:

// The Event-Callback:
private void Sender_Recieve(object sender, ErrorCode e)
{
  lastError = e;
  semaphore.Release();
}

// The SendPacket method:
public async Task<ErrorCode> SendPacketAsync(Packet packet)
{
  // send packet

  await semaphore.WaitAsync();

  return lastError;
}

So is there any way of doing this faster/better without performance-loss?

Aman Agnihotri
  • 2,973
  • 1
  • 18
  • 22
Nerix
  • 53
  • 1
  • 5

1 Answers1

6

This would be a good use for TaskCompletionSource, which allows you to set up an awaitable object and set it in the callback, signaling the awaiter.

TaskCompletionSource<ErrorCode> source = null;

private void Sender_Recieve(object sender, ErrorCode e)
{
    source.SetResult(e);
}

public async Task<ErrorCode> SendPacketAsync(Packet packet)
{
    source = new TaskCompletionSource<ErrorCode>();
    //send packet
    return await source.Task;
}
John Wu
  • 50,556
  • 8
  • 44
  • 80