我有几个异步网络操作,它们返回可能永远不会完成的任务:
-
UdpClient.ReceiveAsync
不接受CancellationToken
-
TcpClient.GetStream
返回一个NetworkStream
这不尊重CancellationToken
on Stream.ReadAsync
(仅在操作开始时检查取消)
双方都等待一条消息may永远不会来(例如由于数据包丢失或无响应)。这意味着我有phantom永远不会完成的任务、永远不会运行的延续以及暂停使用的套接字。我知道我可以使用TimeoutAfter,但这只能解决连续性问题。
那我该怎么办呢?
所以我做了一个扩展方法IDisposable
这创造了一个CancellationToken
超时后处理连接,因此任务完成并且一切继续:
public static IDisposable CreateTimeoutScope(this IDisposable disposable, TimeSpan timeSpan)
{
var cancellationTokenSource = new CancellationTokenSource(timeSpan);
var cancellationTokenRegistration = cancellationTokenSource.Token.Register(disposable.Dispose);
return new DisposableScope(
() =>
{
cancellationTokenRegistration.Dispose();
cancellationTokenSource.Dispose();
disposable.Dispose();
});
}
而且使用方法也极其简单:
try
{
var client = new UdpClient();
using (client.CreateTimeoutScope(TimeSpan.FromSeconds(2)))
{
var result = await client.ReceiveAsync();
// Handle result
}
}
catch (ObjectDisposedException)
{
return null;
}
额外信息:
public sealed class DisposableScope : IDisposable
{
private readonly Action _closeScopeAction;
public DisposableScope(Action closeScopeAction)
{
_closeScopeAction = closeScopeAction;
}
public void Dispose()
{
_closeScopeAction();
}
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)