bub*_*ing 6 .net c# task-parallel-library
我目前正在尝试Task.Delay()在必须以.Net 4.0为目标的程序中实现.Net 4.5的替代方法.我在这个博客上找到了以下代码.
/* You can write Task-based asynchronous methods by utilizing a TaskCompletionSource.
A TaskCompletionSource gives you a 'slave' Task that you can manually signal.
Calling SetResult() signals the task as complete, and any continuations kick off. */
void Main()
{
for (int i = 0; i < 10000; i++)
{
Task task = Delay (2000);
task.ContinueWith (_ => "Done".Dump());
}
}
Task Delay (int milliseconds) // Asynchronous NON-BLOCKING method
{
var tcs = new TaskCompletionSource<object>();
new Timer (_ => tcs.SetResult (null)).Change (milliseconds, -1);
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)
Tasks对我来说相当新鲜. System.Threading.Timer并且TaskCompletionSource对我来说是全新的(截至今天),我正在与他们挣扎.除此之外,我想知道如何CancellationToken为此代码添加功能.我假设我可以Delay()像这样在方法中添加一个参数:
Task Delay (int milliseconds, CancellationToken token) // Asynchronous NON-BLOCKING method
{
var tcs = new TaskCompletionSource<object>();
new Timer (_ => tcs.SetResult (null)).Change (milliseconds, -1);
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)
...但是,我在哪里放置检查令牌和退出方法的逻辑?在回调的某个地方?这甚至可能吗?
我尝试尽可能少地更改您的代码,但这里有一个工作示例,其行为方式与 Task.Delay 相同。
需要注意的是,我使用了TrySetCanceled和 ,TrySetResult因为计时器可以在任务取消后完成。理想情况下你想停止计时器。
另请注意,取消的任务将引发TaskCanceledException
static void Main(string[] args)
{
// A cancellation source that will cancel itself after 1 second
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(1));
try
{
// This will only wait 1 second because as it will be cancelled.
Task t = Delay(5000, cancellationTokenSource.Token);
t.Wait();
Console.WriteLine("The task completed");
}
catch (AggregateException exception)
{
// Expecting a TaskCanceledException
foreach (Exception ex in exception.InnerExceptions)
Console.WriteLine("Exception: {0}", ex.Message);
}
Console.WriteLine("Done");
Console.ReadLine();
}
private static Task Delay(int milliseconds, CancellationToken token)
{
var tcs = new TaskCompletionSource<object>();
token.Register(() => tcs.TrySetCanceled());
Timer timer = new Timer(_ => tcs.TrySetResult(null));
timer.Change(milliseconds, -1);
return tcs.Task;
}
Run Code Online (Sandbox Code Playgroud)
多读一点你的问题。如果您需要 Task.Delay 并且您的目标是 .NET 4.0,那么您应该使用http://www.nuget.org/packages/Microsoft.Bcl.Async/中的 Microsoft Async nuget 包,它包含该方法TaskEx.Delay
| 归档时间: |
|
| 查看次数: |
2933 次 |
| 最近记录: |