Bezdepbonusu7Программирование: статьи и ответы

Вопрос

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

Автор вопроса: SlagggОтветов: 3

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

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

Спасибо.

task-parallel-library

Ответы

Ответ 1 · рейтинг 22 · Glenn Slayden

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

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

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

Ответ 2 · рейтинг 11 · Mike Hadlow

Вы можете написать свою собственную функцию 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 · рейтинг 2 · Jim Mischel

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

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы