Подтвердить что ты не робот

Как запланировать задачу для будущего выполнения в параллельной библиотеке задач

Есть ли способ запланировать выполнение задачи в будущем с помощью параллельной библиотеки задач?

Я понимаю, что я мог бы сделать это с помощью пред-.NET4-методов, таких как System.Threading.Timer... однако, если есть способ TPL для этого, я предпочел бы оставаться в рамках структуры. Однако я не могу его найти.

Спасибо.

4b9b3361

Ответ 1

Эта функция была введена в Async CTP, который теперь включен в .NET 4.5. Выполнение его следующим образом не блокирует поток, но возвращает задачу, которая будет выполняться в будущем.

Task<MyType> new_task = Task.Delay(TimeSpan.FromMinutes(5))
                            .ContinueWith<MyType>( /*...*/ );

(Если вы используете старые релизы Async, используйте статический класс TaskEx вместо Task)

Ответ 2

Вы можете написать свою собственную функцию 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;
    }

Используйте его следующим образом:

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

Ответ 3

Установите таймер с одним выстрелом, который при запуске запускает задачу. Например, приведенный ниже код будет ждать пять минут до начала выполнения задачи.

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

TimeSpan.FromMilliseconds(-1) делает таймер одним выстрелом, а не периодическим таймером.