我正在开发一个可以通过网络来回发送结构化消息的库。该库有一个Send
方法,该方法将Action
作为回调。 调用Send
时,消息将发送到服务器,当收到对该消息的响应时,将检索并执行存储的回调。
这一切都完美运行,但我想添加一个包装Send
的SendAsync
方法,以便可以使用 async/await 而不是直接传递Action
。 我已经让它工作了,但我不知道我是否正确,或者我以后是否会遇到问题。 有一句话特别困扰着我。
Send
看起来像这样:
public void Send(Packet packet, Action<Response> callback)
{
if (packet is Request)
{
RegisterResponseCallback(packet, callback);
}
Send(packet);
}
异步SendAsync
如下所示:
public Task<Response> SendAsync(Request request)
{
var tcs = new TaskCompletionSource<Response>();
Send(request, (response) => { tcs.TrySetResult(response); });
return tcs.Task;
}
我用这段代码调用了SendAsync
几次,我以正确的顺序和正确的时间得到了正确的响应:
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);
困扰我的那条线是那条叫Connected
的线。 它位于一个由于各种原因我不想标记async
的方法中。
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;
}
}
具体来说,读(new Task(async () => { await Connected(); })).Start();
的那行对我来说真的很"臭",但这是我能想到让Visual Studio停止给我警告的唯一方法。
我是否为 async/await 正确包装了Send
,或者我在这里所做的任何事情都会给我带来进一步的问题? 有没有更好的方式让我打电话给Connected
?
我认为StatusChanged
是事件处理程序?因此,您需要async void
.
protected override async void StatusChanged(NetIncomingMessage message)
{
//use await here
}
编辑 由于它不是事件处理程序,并且您有各种理由不将其标记为async
,我能给出的唯一建议是:使用 Task.Run
而不是 new Task
,如果您不想更改方法的签名,这可能是最合适的解决方案。
Task.Run(async() => await Connected());
new Task
与Task.Factory.StartNew
Task.Run
与Task.Factory.StartNew