c# – 在.Net 4.0中使用差的mans async / await构造实现异步超时

前端之家收集整理的这篇文章主要介绍了c# – 在.Net 4.0中使用差的mans async / await构造实现异步超时前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
动机

C#5.0异步/等待构造非常棒,但遗憾的是,微软只展示了.NET 4.5和VS 2012的候选版本,这些技术将在我们的项目中得到广泛采用需要一些时间.

在Stephen Toub的Asynchronous methods,C# iterators,and Tasks中,我找到了一个可以很好地用于.NET 4.0的替代品.还有十几个其他实现甚至可以在.NET 2.0中使用该方法,尽管它们看起来很少过时且功能较少.

所以现在我的.NET 4.0代码看起来像(注释部分显示它是如何在.NET 4.5中完成的):

//private async Task ProcessMessageAsync()
private IEnumerable<Task> ProcessMessageAsync()
{
    //var udpReceiveResult = await udpClient.ReceiveAsync();

    var task = Task<UdpAsyncReceiveResult>
               .Factory
               .FromAsync(udpClient.BeginReceive,udpClient.EndReceive,null);

    yield return task;

    var udpReceiveResult = task.Result;

    //... blah blah blah

    if (message is BootstrapRequest)
    {
        var typedMessage = ((BootstrapRequest)(message));

        // !!! .NET 4.0 has no overload for CancellationTokenSource that 
        // !!! takes timeout parameter :(
        var cts 
          = new CancellationTokenSource(BootstrapResponseTimeout); // Error here

        //... blah blah blah

        // Say(messageIPEndPoint,responseMessage,cts.Token);

        Task.Factory.Iterate(Say(messageIPEndPoint,cts.Token));
    }
}

看起来有点难看虽然它能完成这项工作

这个问题

在.NET 4.5中使用CancellationTokenSource时,有一个构造函数将时间跨度作为超时参数,因此生成的CancellationTokenSource在指定的时间段内取消.
.Net 4.0无法超时,那么在.Net 4.0中这样做的正确方法是什么?

解决方法

这真的与async / await有关吗?看起来你只需要一种取消令牌的方法,独立于异步/等待,对吗?在这种情况下,您可以简单地创建一个在超时后调用取消的Timer吗?
new Timer(state => cts.Cancel(),null,BootstrapResponseTimeout,Timeout.Infinite);

编辑

我上面的初步回答是基本思路,但是在Is CancellationTokenSource.CancelAfter() leaky?中可以找到更强大的解决方案(实际上是你正在寻求的构造函数的.Net 4.5实现).这是一个可用于根据该代码创建超时令牌的函数.

public static CancellationTokenSource CreateTimeoutToken(int dueTime) {
    if (dueTime < -1) {
        throw new ArgumentOutOfRangeException("dueTime");
    }
    var source = new CancellationTokenSource();
    var timer = new Timer(self => {
        ((Timer)self).Dispose();
        try {
            source.Cancel();
        } catch (ObjectDisposedException) {}
    });
    timer.Change(dueTime,-1);
    return source;
}
原文链接:https://www.f2er.com/csharp/243376.html

猜你在找的C#相关文章