I'm working on a library that can send structured messages back and forth across the network. The library has a Send
method that takes takes an Action
as a callback. When Send
is called, the message is sent to the server, when a response is received to that message the stored callback is retrieved and executed.
This all works perfectly, but I would like to add a SendAsync
method that wraps Send
so that async / await can be used instead of directly passing an Action
. I've gotten it to work, but I don't know If I'm doing it correctly, or if I'll run in to problems later. There is one line in particular that is really bothering me.
Send
looks like this:
public void Send(Packet packet, Action<Response> callback)
{
if (packet is Request)
{
RegisterResponseCallback(packet, callback);
}
Send(packet);
}
The async SendAsync
looks like this:
public Task<Response> SendAsync(Request request)
{
var tcs = new TaskCompletionSource<Response>();
Send(request, (response) => { tcs.TrySetResult(response); });
return tcs.Task;
}
I'm calling SendAsync
a few time with this code, and I get the correct responses back in the correct order with the correct timing:
private async Task Connected()
{
Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 1" })).Message);
Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 2" })).Message);
Console.WriteLine((await SendAsync(new EchoRequest() { Text = "Test 3" })).Message);
The line that is bothering me is the one that calls Connected
. It's inside a method that I don't want to mark async
for various reasons.
protected override void StatusChanged(NetIncomingMessage message)
{
switch (message.SenderConnection.Status)
{
case NetConnectionStatus.Connected:
_serverConnection = new ServerConnection(this, message.SenderConnection);
(new Task(async () => { await Connected(); })).Start();
break;
}
}
Specifically, the line that reads (new Task(async () => { await Connected(); })).Start();
feels really "smelly" to me, but this was the only way I could figure out to get Visual Studio to stop giving me warnings.
Have I wrapped Send
correctly for async /await, or will anything I've done here cause me problems further down the line? Is there a better way for me to call Connected
?
I think StatusChanged
is an event handler? Thus you need async void
.
protected override async void StatusChanged(NetIncomingMessage message)
{
//use await here
}
EDIT Since it's not an event handler, and you have various reasons not to mark it async
, the only suggestion I can give is: using Task.Run
instead of new Task
, it's probably the most suitable solution here if you don't want to change the signature of the method.
Task.Run(async() => await Connected());
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.