使用异步芒实施不佳异步超时/伺机在.NET 4.0中构造 [英] Implementing async timeout using poor mans async/await constructs in .Net 4.0

查看:148
本文介绍了使用异步芒实施不佳异步超时/伺机在.NET 4.0中构造的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C#5.0异步/等待结构是真棒,但不幸的是微软只表示双方.NET 4.5和VS 2012候选版本,它需要一定的时间,直到这些技术将在我们的项目中得到广泛采用。

C# 5.0 async/await constructs are awesome, unfortunately yet Microsoft only shown a release candidate of both .NET 4.5 and VS 2012, and it will take some time until these technologies will get widely adopted in our projects.

在斯蒂芬Toub的异步方法,C#迭代器和我发现,可以在.NET 4.0中可以很好地用于替换任务。还有其他的实现就可以使用这种方法,即使在.NET 2.0,虽然他们似乎有点过时,少功能丰富,让一打。

In Stephen Toub's Asynchronous methods, C# iterators, and Tasks I've found a replacement that can be nicely used in .NET 4.0. There are also a dozen of other implementations that make it possible using the approach even in .NET 2.0 though they seem little outdated and less feature-rich.

所以,现在我的.NET 4.0 code样子(注释的部分显示它是如何在.NET 4.5完成):

So now my .NET 4.0 code looks like (the commented sections show how it is done in .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, responseMessage, cts.Token));
    }
}

虽然它的工作看起来有点丑

Looks little ugly though it does the job

在使用 CancellationTokenSource .NET 4.5有是采用时间跨度为一个超时参数,构造函数,以便产生 CancellationTokenSource 的指定时间内取消。结果
.NET 4.0不能超时,那么什么是这样做在.NET 4.0中的正确方法是什么?

When using CancellationTokenSource in .NET 4.5 there is a constructor that takes timespan as a timeout parameter, so that resulting CancellationTokenSource cancels within specified period of time.
.Net 4.0 is not able to timeout, so what is the correct way of doing that in .Net 4.0?

推荐答案

这是否真的有什么关系异步/等待?看起来你只是需要一个方法来取消的道理,独立异步电动机/ AWAIT,对不对?在这种情况下,可能你只需创建一个调用超时之后取消计时器?

Does this really have anything to do with async/await? Looks like you're just needing a way to cancel the token, independently of async/await, right? In that case, could you simply create a Timer that calls Cancel after the timeout?

new Timer(state => cts.Cancel(), null, BootstrapResponseTimeout, Timeout.Infinite);

修改

我上面的初步反应是基本的想法,但一个更强大的解决方案可在发现是CancellationTokenSource .CancelAfter()漏水?(实际上是.NET 4.5实现你正在寻找的构造)。下面是你可以用它来创建基于code超时令牌的功能。

My initial response above is the basic idea, but a more robust solution is can be found in Is CancellationTokenSource.CancelAfter() leaky? (actually the .Net 4.5 implementation of the constructor you're seeking). Here's a function you can use to create timeout tokens based on that code.

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;
}

这篇关于使用异步芒实施不佳异步超时/伺机在.NET 4.0中构造的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆