如何在任务并行库中安排任务以便将来执行

Sla*_*ggg 12 .net-4.0 task-parallel-library

有没有办法使用任务并行库来安排将来执行的任务?

我意识到我可以使用.NET4之前的方法来实现这一点,例如System.Threading.Timer ......但是如果有TPL方法可以做到这一点,我宁愿留在框架的设计中.但是我找不到一个.

谢谢.

Gle*_*den 22

此功能是在Async CTP中引入的,现在已经转换为.NET 4.5.按如下方式执行此操作不会阻止该线程,但会返回将在以后执行的Task.

Task<MyType> new_task = Task.Delay(TimeSpan.FromMinutes(5))
                            .ContinueWith<MyType>( /*...*/ );
Run Code Online (Sandbox Code Playgroud)

(如果使用旧的Async版本,请使用静态类TaskEx而不是Task)


Mik*_*low 11

您可以编写自己的RunDelayed函数.这需要延迟和延迟完成后运行的功能.

    public static Task<T> RunDelayed<T>(int millisecondsDelay, Func<T> func)
    {
        if(func == null)
        {
            throw new ArgumentNullException("func");
        }
        if (millisecondsDelay < 0)
        {
            throw new ArgumentOutOfRangeException("millisecondsDelay");
        }

        var taskCompletionSource = new TaskCompletionSource<T>();

        var timer = new Timer(self =>
        {
            ((Timer) self).Dispose();
            try
            {
                var result = func();
                taskCompletionSource.SetResult(result);
            }
            catch (Exception exception)
            {
                taskCompletionSource.SetException(exception);
            }
        });
        timer.Change(millisecondsDelay, millisecondsDelay);

        return taskCompletionSource.Task;
    }
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

    public void UseRunDelayed()
    {
        var task = RunDelayed(500, () => "Hello");
        task.ContinueWith(t => Console.WriteLine(t.Result));
    }
Run Code Online (Sandbox Code Playgroud)


Jim*_*hel 2

设置一个一次性计时器,一旦触发,就会启动任务。例如,下面的代码将在开始任务之前等待五分钟。

TimeSpan TimeToWait = TimeSpan.FromMinutes(5);
Timer t = new Timer((s) =>
    {
        // start the task here
    }, null, TimeToWait, TimeSpan.FromMilliseconds(-1));
Run Code Online (Sandbox Code Playgroud)

TimeSpan.FromMilliseconds(-1)使得计时器成为一次性计时器而不是周期性计时器。