В чем разница с Continue с и без? - PullRequest
0 голосов
/ 01 ноября 2019

Я запускаю эти две версии, и кажется, что каждая из них выдает мне один и тот же вывод, который является последовательным. эта ошибка:

Невозможно неявно преобразовать тип 'void' в 'System.Threading.Tasks.Task'

Task t = Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b())
        .Wait();

static void ContinueWith_Method1a()
{
    System.Console.WriteLine("Continue With Method 1a started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1a completed.");
}

static void ContinueWith_Method1b()
{
    System.Console.WriteLine("Continue With Method 1b started.");
    Thread.Sleep(1000);// Simulate task processing time.

    System.Console.WriteLine("Continue With Method 1b completed.");
}

Ответы [ 2 ]

2 голосов
/ 01 ноября 2019

ContinueWith запускает следующую задачу после первого завершения. Таким образом, оба ваших примера выполняются синхронно (сначала метод A, а затем метод b)

РЕДАКТИРОВАТЬ:

В дополнение к вашему редактированию ваша ошибка вызвана функцией .Wait(), которая ожидает Задачуи возвращает недействительным.

1 голос
/ 01 ноября 2019

В чем разница с ContinueWith и без?

Заголовочный вопрос вашего сообщения очень вводит в заблуждение. Использование ContinueWith() в ваших примерах кода является наименьшим интересным отличием. Гораздо более существенное различие заключается в том, что первый пример просто вызывает методы напрямую, а во втором используется Task.Run().

Теперь, как это происходит, не было бы никакой причины писать код, как во втором примере. Даже игнорируя аспект ContinueWith(), если все, что ваша задача делает, это вызывает метод, и все, что вы собираетесь делать с ней, - это синхронно ждать ее (то есть вызывать метод Wait()), тогда вы также можетепросто вызовите этот метод в вашей текущей теме. В этой ситуации Task.Run() не требуется.

Точно так же, если все, что вы собираетесь сделать с ContinueWith(), это сразу же после этого вызвать другой метод, вы можете просто вызвать метод напрямую.

Блокируя в текущем потоке, вы теряете бесполезное преимущество, которое могло бы иметь место при выполнении этих двух методов асинхронно.

Конечно, существует явная механическая разница. В конечном итоге вы получаете те же результаты, но то, как этот результат достигается, сильно отличается. В первом примере вы просто вызываете методы один за другим. Каждый вызов выполняется в текущем потоке. Во втором примере вы, по сути, просите пул потоков выполнять каждый метод последовательно, в то время как вы блокируете текущий поток, ожидая, что это произойдет.

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

Наконец, насколько вы получили сообщение об ошибке, Msgstr "Невозможно неявно преобразовать тип 'void' в 'System.Threading.Tasks.Task'" , это произошло только потому, что вы добавили переменную Task t и попытались установить ее в результат метода Wait(). Поскольку метод Wait() ничего не возвращает (т.е. имеет объявленный тип возврата void), не говоря уже о значении Task, невозможно установить значение t, используя его возвращаемое значение. Отсюда и сообщение об ошибке. Если вы хотите назначить переменную Task, вам нужно просто пропустить вызов Wait():

Task t = Task.Run(() => ContinueWith_Method1a())
        .ContinueWith(task => ContinueWith_Method1b());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...