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

Множественная параллельная задача. Продолжение с порядком выполнения

Вопрос

Это, наверное, что-то простое, что я пропустил.

Скажем, я делаю (в Loveley VB):

Dim t1 As New Task(Sub() Debug.WriteLine("t1"))
Dim t2 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t2"))
Dim t3 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t3"))
t1.Start()

Обратите внимание: t1.ContinueWith используется дважды. Каков предпочтительный порядок выполнения этих задач? Для меня это случайное или неправильное.

Почему?

Причина, по которой я хочу это сделать...

  • Создать задачу захвата и возврата данных
  • После выполнения задачи, которая "сортирует" пользовательский интерфейс на TaskScheduler.FromCurrentSynchronizationContext() (поток пользовательского интерфейса)
  • Следуйте первоначальной задаче захвата данных, преобразуя данные в длинный отчет (требуется возраст)
  • Вернитесь в поток пользовательского интерфейса, присвойте этому отчету элементу управления предварительным просмотром
  • Очистка (избавиться от моей анимации прогресса и т.д.)

Это усложняется тем фактом, что шаг 4 является необязательным.

Посреди всего этого мои задачи гибки назад, чтобы установить свойства элемента, чтобы пользовательский интерфейс и задачи могли играть хорошо. Возможно, я должен полностью удалить результат задачи и просто придерживаться Synclocking моих переменных-членов. Все они назначаются только один раз после.

Спасибо, Том

4b9b3361

Ответ 1

Задачи выполняются в порядке LIFO для лучшей локальности памяти. Это может быть изменено, конечно, если вы используете планировщик differnt или если MS решит "исправить" оригинал. Я не думаю, что вы должны полагаться на это поведение. Вместо этого вы можете распаковать свою задачу, чтобы продолжить работу над предыдущей задачей, когда она завершилась. В противном случае вы ждете не того. Более подробную информацию можно найти здесь: http://msdn.microsoft.com/en-us/library/ee795275.aspx

Ответ 2

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

Dim t1 As New Task(Sub() Debug.WriteLine("t1"))
Dim t2 As Task = t1.ContinueWith(Sub() Debug.WriteLine("t2"))
Dim t3 As Task = t2.ContinueWith(Sub() Debug.WriteLine("t3"))
t1.Start()

Если t2 и t3 были длинными, они будут выполняться параллельно, как вы это делали.

Нет необходимости создавать настраиваемый планировщик задач, чтобы изменить это поведение.

Ответ 3

Основываясь на вашем комментарии к ответу Яна Мерсера, я бы предложил что-то вроде

Task t1 = new Task((_)=>Console.WriteLine("t1"));
Task tn = secondTaskCondition ? t1.ContinueWith((_)=>Console.WriteLine("t2")) : t1;
Task t3 = tn.ContinueWith((_)=>Console.WriteLine("t3"));
t1.Start();

Это дает вам детерминированное выполнение и по-прежнему позволяет вам компоновать рабочий процесс с помощью дополнительных модулей.