Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/264.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是使用async/await回调包装方法的正确方法吗?_C#_Async Await - Fatal编程技术网

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();})。我收到关于“未等待连接”的警告,尝试等待它告诉我需要更改
状态
,然后我就回到了开始时不喜欢我原来的线路的地方。