Множественная параллельная задача .Континезвит по порядку исполнения
-
26-09-2019 - |
Вопрос
Вопрос
Это, вероятно, что-то простое, которое я пропустил.
Допустим, я делаю (в Ловели В.Б.):
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()
(UI TOTE) - Следуйте исходным задачам Grabbing данных, преобразовав данные в длительный отчет (занимает возраст)
- Вернуться на ui поток, назначить этот отчет перед предварительным просмотром контроля
- Очистка (избавиться от моей анимации прогресса и т. Д.)
Это сделано более осложненным тем, что шаг 4 необязательный.
Среди всех этого мои задачи наклоняются назад, чтобы установить свойства участника, чтобы пользовательские пользователи и задачи могут играть приятно. Возможно, я должен полностью бросить целую задачу и просто придерживаться синхронизации моих переменных членов. Все они только присваиваются только один раз.
Спасибо, Том.
Решение
Задачи выполняются в информировании LIFO для лучшего населенного пункта памяти. Это может быть изменено, конечно, если вы используете разный планировщик или если MS решит «исправить» оригинальный. Я не думаю, что вы должны полагаться на это поведение. Вместо этого вы можете развернуть вашу задачу, чтобы продолжить работу над предыдущей задачей, когда она завершила. В противном случае вы ждете не той вещь. Больше инфо можно найти здесь: http://msdn.microsoft.com/en-us/library/ee795275.aspx.
Другие советы
Если вы хотите обеспечить применение порядка между 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 долго работали, они будут выполняться параллельно, так как вы его написали.
Нет необходимости создавать пользовательский планировщик задач для изменения этого поведения.
Исходя из вашего комментария к ответу Мерсера Ян, я бы предложил бы что-то вроде
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();
Это дает вам детерминированное исполнение и до сих пор позволяет создавать ваш рабочий процесс с дополнительными блоками.