加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 取消.Net 4.0中的任务延迟

发布时间:2020-12-15 08:46:24 所属栏目:百科 来源:网络整理
导读:我目前正在尝试在必须以.Net 4.0为目标的程序中实现.Net 4.5的Task.Delay()方法的替代品.我在 this blog找到了以下代码. /* You can write Task-based asynchronous methods by utilizing a TaskCompletionSource.A TaskCompletionSource gives you a 'slave
我目前正在尝试在必须以.Net 4.0为目标的程序中实现.Net 4.5的Task.Delay()方法的替代品.我在 this blog找到了以下代码.
/* 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;
}

任务对我来说都是新手. 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;
}

…但是,我在哪里放置检查令牌和退出方法的逻辑?在回调的某个地方?这甚至可能吗?

解决方法

我试图尽可能少地更改你的代码,但这是一个工作示例,其行为与Task.Delay相同.

重要的是要注意我使用TrySetCanceled和TrySetResult,因为Timer可以在任务取消后完成.理想情况下,您想要停止计时器.

另请注意,取消的任务将抛出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;
}

再读一下你的问题.如果您需要Task.Delay并且您的目标是.NET 4.0,那么您应该使用http://www.nuget.org/packages/Microsoft.Bcl.Async/中的Microsoft Async nuget包它包含方法TaskEx.Delay

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读