【发布时间】:2026-01-05 05:05:03
【问题描述】:
动机
C# 5.0 async/await 结构非常棒,但不幸的是,微软只展示了 .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, responseMessage, cts.Token));
}
}
看起来有点难看,虽然它可以完成这项工作
问题
在 .NET 4.5 中使用 CancellationTokenSource 时,有一个将时间跨度作为超时参数的构造函数,因此生成的 CancellationTokenSource 在指定时间段内取消。
.Net 4.0 无法超时,那么在 .Net 4.0 中这样做的正确方法是什么?
【问题讨论】:
-
将标题中的“timer”更改为“timeout”,因为问题是关于超时的,而“timer”(用于在某些周期执行中重复出现)具有误导性和迷惑性
标签: c# timeout pattern-matching task-parallel-library async-await