i3a*_*non 6 c# networking idisposable async-await cancellation-token
我有几个异步网络操作返回可能永远不会完成的任务:
UdpClient.ReceiveAsync 不接受 CancellationTokenTcpClient.GetStream返回NetworkStream不尊重CancellationTokenon的Stream.ReadAsync(仅在操作开始时检查取消)两者都在等待可能永远不会发生的消息(例如因丢包或没有响应).这意味着我有永远不会完成的幻像任务,永远不会运行的延续和使用套接字.我知道我可以使用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();
});
}
Run Code Online (Sandbox Code Playgroud)
用法非常简单:
try
{
var client = new UdpClient();
using (client.CreateTimeoutScope(TimeSpan.FromSeconds(2)))
{
var result = await client.ReceiveAsync();
// Handle result
}
}
catch (ObjectDisposedException)
{
return null;
}
Run Code Online (Sandbox Code Playgroud)
额外信息:
public sealed class DisposableScope : IDisposable
{
private readonly Action _closeScopeAction;
public DisposableScope(Action closeScopeAction)
{
_closeScopeAction = closeScopeAction;
}
public void Dispose()
{
_closeScopeAction();
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5435 次 |
| 最近记录: |