首先感谢您的阅读。 我在这里是因为在我的一个项目中,我不断地在循环中接收数据包,但是当我关闭我的应用程序时,我从我的ReceivePackets方法(在ReceiveLoop中调用)得到了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循环之后放置一些内容时,甚至没有进行打印。
答案 0 :(得分:4)
这是因为ReceiveLoop
实际上在所有代码完成之前就“返回”了,就像大多数async
方法一样。您需要使它返回Task
,然后等待它,而不是根据该操作创建新的Task
。
private async Task ReceiveLoop()
{
while (_client.Connected && _run)
{
await ReceivePackets();
}
}
...
_receiveTask = ReceiveLoop();