这是用异步/等待的回调包装方法的正确方法吗?



我正在开发一个可以通过网络来回发送结构化消息的库。该库有一个Send方法,该方法将Action作为回调。 调用Send时,消息将发送到服务器,当收到对该消息的响应时,将检索并执行存储的回调。

这一切都完美运行,但我想添加一个包装SendSendAsync方法,以便可以使用 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 TaskTask.Factory.StartNew

Task.RunTask.Factory.StartNew

最新更新