Я работаю над интерфейсом в .NET Core для старой консоли освещения и в настоящее время внедряю пакеты. Основная идея этого интерфейса /API заключается в следующем: клиент отправляет свои пакеты на один порт UDP, а консоль отвечает кодом ошибки. Консоль отправляет свои пакеты через другой порт UDP.
Поэтому, когда я проектировал API, я просто использовал Action<ErrorCode>
качестве функции обратного вызова. Но этот метод не очень практичен при работе с несколькими пакетами одновременно.
У моего UdpClient возникает событие, возникающее при получении пакетов, но консоль не возвращает более 4-байтового кода ошибки.
Итак, я попробовал это с помощью SemaphoreSlim
.
Моя идея - позволить отправителю дождаться события и выпустить семафор. Вопрос в основном в том, является ли это самым быстрым и "чистым" способом решения этой проблемы:
// 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;
}
Так есть ли способ сделать это быстрее/лучше без потери производительности?
Это было бы хорошим использованием для TaskCompletionSource, который позволяет вам установить ожидаемый объект и установить его в обратном вызове, сигнализируя ожидающему.
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;
}