c# - await a Task with a loop 谁也在等待

标签 c# async-await

首先感谢阅读。 我来这里是因为在我的一个项目中,我在一个循环中连续接收数据包,但是当我关闭我的应用程序时,我从 ReceiveLoop 中调用的 ReceivePackets 方法中得到一个 ObjectDisposedException,所以我觉得还好,我只是必须等到 _receiveTask 完成后才能关闭我的流和 tcp 客户端,但我的 _receiveTask 甚至没有到达方法的末尾就返回完成。

我试过使用线程代替,但同样的问题

开始任务

if (_receiveTask == null)
{
    _receiveTask = Task.Run(new Action(ReceiveLoop));
}

在任务中循环

private async void ReceiveLoop()
{
    while (_client.Connected && _run)
    {
        await ReceivePackets();
    }
}

收包任务

private async Task<List<Packet>> ReceivePackets()
{
    var bytes = new byte[_client.ReceiveBufferSize];
    int size = await _stream.ReadAsync(bytes, 0, bytes.Length);
    List<Packet> packets = Decrypt(bytes, size).Select(p => new Packet(p)).ToList();
    foreach (var packet in packets)
    {
        Dispatch(() => PacketReceived?.Invoke(packet));
    }
    return packets;
}

使用的停止方法

public async Task Stop()
{
    if (_client.Connected)
    {
        _run = false;
        await _receiveTask;
        _stream.Close();
        _client.Close();
    }
}

在 Stop 方法中,_receiveTask 被认为已完成,但是当我在 ReceiveLoop 的 while 循环之后打印一些东西时,它甚至没有被打印出来。

最佳答案

那是因为 ReceiveLoop 实际上会在其所有代码完成之前“返回”,就像大多数 async 方法一样。您需要让它返回一个 Task,然后等待它,而不是基于该操作创建一个新的 Task

private async Task ReceiveLoop()
{
    while (_client.Connected && _run)
    {
        await ReceivePackets();
    }
}

...

_receiveTask = ReceiveLoop();

关于c# - await a Task with a loop 谁也在等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56528634/

相关文章:

javascript - 循环内出现意外的 `await`。 (无等待循环)

node.js - 将异步等待查询包装在 try catch 中

c# - 我可以在单个序列化程序的上下文中覆盖 Json.Net 成员名称映射吗?

c# - 为什么未等待的异步方法不抛出异常?

c# - 异步读取文件的正确方法

c# - 为什么 async/await 在我的 ASP.net 5 控制台应用程序中不起作用?

c# - 在Mysql中使用正确的语法错误

c# - 根据xml中的信息过滤列表

c# - 使用 Windows 服务手动实现 IoC

c# - 如何将依赖项注入(inject) asp.net core 2.0 中的自定义 ILogger?