C# 这是使用async/await回调包装方法的正确方法吗?
我正在开发一个可以通过网络来回发送结构化消息的库。该库有一个C# 这是使用async/await回调包装方法的正确方法吗?,c#,async-await,C#,Async Await,我正在开发一个可以通过网络来回发送结构化消息的库。该库有一个Send方法,该方法将操作作为回调。调用Send时,消息被发送到服务器,当收到对该消息的响应时,检索并执行存储的回调 这一切都很完美,但我想添加一个sendascent方法,该方法包装Send,以便可以使用async/await,而不是直接传递操作。我已经让它工作了,但我不知道我是否做得正确,或者我以后是否会遇到问题。有一句话特别让我困扰 Send如下所示: public void Send(Packet packet, Action&
Send
方法,该方法将操作作为回调。调用Send
时,消息被发送到服务器,当收到对该消息的响应时,检索并执行存储的回调
这一切都很完美,但我想添加一个sendascent
方法,该方法包装Send
,以便可以使用async/await,而不是直接传递操作。我已经让它工作了,但我不知道我是否做得正确,或者我以后是否会遇到问题。有一句话特别让我困扰
Send
如下所示:
public void Send(Packet packet, Action<Response> callback)
{
if (packet is Request)
{
RegisterResponseCallback(packet, callback);
}
Send(packet);
}
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;
}
}
具体来说,读取(新任务(async()=>{await Connected();})的行)
对我来说真的很“臭”,但这是我唯一能找到的让VisualStudio停止给我警告的方法
我是否为async/await正确包装了Send
,或者我在这里所做的任何事情都会导致后续问题?有没有更好的方法让我调用Connected
?我认为StatusChanged
是一个事件处理程序?因此,您需要异步void
protected override async void StatusChanged(NetIncomingMessage message)
{
//use await here
}
EDIT由于它不是一个事件处理程序,并且您有各种理由不将其标记为async
,因此我能给出的唯一建议是:使用Task.Run
而不是new Task
,如果您不想更改方法的签名,它可能是最合适的解决方案
Task.Run(async() => await Connected());
我想StatusChanged
是一个事件处理程序吗?因此,您需要异步void
protected override async void StatusChanged(NetIncomingMessage message)
{
//use await here
}
EDIT由于它不是一个事件处理程序,并且您有各种理由不将其标记为async
,因此我能给出的唯一建议是:使用Task.Run
而不是new Task
,如果您不想更改方法的签名,它可能是最合适的解决方案
Task.Run(async() => await Connected());
不,它不是事件处理程序。它是从库的更深处调用的,这是从计时器轮询的服务器接收到消息的结果。同样地,async void
感觉是错误的,我读到的所有内容都表明,将非偶数处理程序声明为async void通常是错误的。@BradleyUffner是的,除了事件处理程序之外,我们应该避免使用async void
。它的名字对我来说就像一个事件处理程序。如果这是一个普通的方法,那么为什么不能使它async
?您说过它在一个方法中,出于各种原因我不想将其标记为async
。为什么?我必须更改它才能返回任务,对吗?然后是等待它的任何调用,依此类推,直到我有异步和任务一直到Main
。我承认,我对async/Wait非常陌生,所以我可能误解了什么StatusChanged
根本不是异步发生的,用async标记它并让它返回任务感觉就像我在混合异步模式和我从未打算异步发生的代码。@BradleyUffner更正。是的,“一路向下”。这就是你所说的使用Task.Run
<代码>任务.Run(()=>{Connected();})代码>。我收到关于“连接未被等待”的警告,尝试等待它告诉我需要使状态更改异步,然后我回到开始时不喜欢原始行的位置。不,它不是事件处理程序。它是从库的更深处调用的,这是从计时器轮询的服务器接收到消息的结果。同样地,async void
感觉是错误的,我读到的所有内容都表明,将非偶数处理程序声明为async void通常是错误的。@BradleyUffner是的,除了事件处理程序之外,我们应该避免使用async void
。它的名字对我来说就像一个事件处理程序。如果这是一个普通的方法,那么为什么不能使它async
?您说过它在一个方法中,出于各种原因我不想将其标记为async
。为什么?我必须更改它才能返回任务,对吗?然后是等待它的任何调用,依此类推,直到我有异步和任务一直到Main
。我承认,我对async/Wait非常陌生,所以我可能误解了什么StatusChanged
根本不是异步发生的,用async标记它并让它返回任务感觉就像我在混合异步模式和我从未打算异步发生的代码。@BradleyUffner更正。是的,“一路向下”。这就是你所说的使用Task.Run
<代码>任务.Run(()=>{Connected();})代码>。我收到关于“未等待连接”的警告,尝试等待它告诉我需要更改状态
,然后我就回到了开始时不喜欢我原来的线路的地方。