c# – 异步网络操作永远不会完成

前端之家收集整理的这篇文章主要介绍了c# – 异步网络操作永远不会完成前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有几个异步网络操作返回可能永远不会完成的任务:

> UdpClient.ReceiveAsync不接受CancellationToken
> TcpClient.GetStream返回一个不遵循Stream.ReadAsync上的CancellationToken的NetworkStream(仅在操作开始时检查取消)@H_404_4@

两者都在等待可能永远不会发生的消息(例如因丢包或没有响应).这意味着我有永远不会完成的幻像任务,永远不会运行的延续和使用套接字.我知道我可以使用TimeoutAfter,但这只会解决延续问题.@H_404_4@

那我该怎么办?@H_404_4@

解决方法

所以我在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();
        });
}

用法非常简单:@H_404_4@

try
{
    var client = new UdpClient();
    using (client.CreateTimeoutScope(TimeSpan.FromSeconds(2)))
    {
        var result = await client.ReceiveAsync();
        // Handle result
    }
}
catch (ObjectDisposedException)
{
    return null;
}

额外信息:@H_404_4@

public sealed class DisposableScope : IDisposable
{
    private readonly Action _closeScopeAction;
    public DisposableScope(Action closeScopeAction)
    {
        _closeScopeAction = closeScopeAction;
    }
    public void Dispose()
    {
        _closeScopeAction();
    }
}

猜你在找的C#相关文章