Когда использовать TaskEx.Run против TaskEx.RunEx - PullRequest
8 голосов
/ 18 февраля 2012

Я пытаюсь понять, когда использовать TaskEx.Run.Я предоставил два примера кода, которые я написал ниже, которые дают тот же результат.Чего я не понимаю, так это того, почему я выбрал подход Task.RunEx TaskEx.RunEx. Уверен, что есть веская причина, и я надеялся, что кто-то может меня заполнить.1007 * Я могу добиться таких же результатов, как и

  async Task DoWork(CancellationToken cancelToken)
    {
        int i = 0;
        while (!cancelToken.IsCancellationRequested)
        {
            listBox.Items.Add(i++);
            listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
            await TaskEx.Delay(100, cancelToken);

        }
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (button.Content.ToString() == "Start")
        {
            button.Content = "Stop";
            cts.Dispose();
            cts = new CancellationTokenSource();
            listBox.Items.Clear();
            DoWork(cts.Token);
        }
        else
        {
            button.Content = "Start";
            cts.Cancel();
        }
    }

Ответы [ 3 ]

13 голосов
/ 18 февраля 2012

Используйте TaskEx.Run, если хотите запустить синхронный код в контексте пула потоков.

Используйте TaskEx.RunEx, если хотите запустить асинхронный код в контексте пула потоков.

Стивен Туб имеет два поста в блоге, связанных с различием в поведении:

Это только один из нескольких вариантов создания задач . Если вам не нужно использовать Run / RunEx, то вам не следует. Используйте простые методы async и используйте Run / RunEx, если вам нужно запустить что-то в фоновом режиме.

1 голос
/ 18 февраля 2012

Разница между вашими двумя DoWork() методами заключается в том, что первый (который использует TaskEx.RunEx()) вообще не является асинхронным.Он выполняется полностью синхронно, запускает другую задачу в другом потоке и немедленно возвращает завершенный Task.Если вы await редактировали или Wait() редактировали эту задачу, она не будет ждать, пока внутренняя задача будет завершена.

0 голосов
/ 18 февраля 2012

Task.Run порождает новый поток в большинстве сценариев, насколько я понимаю.

Важно отметить, что просто потому, что вы помечаете метод как асинхронный и используете awaiters, это НЕ (обязательно) означает, что создаются новые потоки, завершения планируются в том же потоке выполнения, из которого они были вызваны в много дел.

Трюк здесь связан с SchedulingContext. Если он установлен для многопоточной квартиры, то вы собираетесь делегировать завершения жизнеспособным потокам в пуле потоков. Если вы находитесь в однопотоковой квартире, как и весь код пользовательского интерфейса WPF и WinForms, то он вернется к вызывающему потоку для завершения, позволяя выполнять работу непосредственно в пользовательском интерфейсе без видимой сортировки потока в коде.

...