c# - 等待带有循环的任务也等待
问题描述
首先感谢您的阅读。我在这里是因为在我的一个项目中,我在一个循环中连续接收数据包,但是当我关闭我的应用程序时,我从我在 ReceiveLoop 中调用的 ReceivePackets 方法获得了一个 ObjectDisposedException,所以我很喜欢,我只是必须等到 _receiveTask 完成才能关闭我的流和 tcp 客户端,但我的 _receiveTask 返回完成,甚至没有到达方法的末尾。
我尝试使用 Thread 但同样的问题
开始任务
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
方法一样。您需要让它返回 aTask
然后等待它,而不是Task
基于该操作创建一个新的。
private async Task ReceiveLoop()
{
while (_client.Connected && _run)
{
await ReceivePackets();
}
}
...
_receiveTask = ReceiveLoop();
推荐阅读
- rest - 空结果 204 或 404 的请求中的 HTTP 返回代码是什么?
- jquery - 使用 jQuery slideDown 或 toggleClass 和 css 过渡添加向下滑动效果
- json - 带有可选成员的 Kotlin 类
- git - git-tag 仅列出当前 HEAD 或以下的那些标签
- javascript - 在map函数中使用三元显示两个选项
- jmeter - 如何使用 Jmeter 测试没有 Varnish 的页面的加载时间
- vba - 将范围乘以当月剩余天数的百分比
- search - 如何根据同一网站上另一个页面的内容在一个页面上搜索关键字?
- angular - 如何为角度前端本地的后端服务器提供服务?
- opennms - 在 OpenNMS 中追踪“打开的文件过多”的原因