Хорошо, таким образом, второй - легкий, поэтому давайте обращаться с тем.
Для второй задачи, t2
, вы ничего не делаете с результатом Задача. Задержка (1000)
. Вы не <кодируете>, ждут это, вы не <кодируете>, Ждут это, и т.д. Учитывая, что метод не async
, я предположил, что вы хотели для него быть блокированием, ждут. Чтобы сделать это, которое вы хотели бы добавить , Ждут()
до конца , Задержка
звонит, чтобы сделать его, блокирование ждет, или просто использует Нить. Сон()
.
Для первой задачи вы кусаетесь тем, что вы используете вар
. Более ясно, что происходит, когда вы не используете вар
:
Task> t1 = Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
});
Вы возвращаете задачу задачи интервал
, не только Задача
интервал
. Внешняя задача "выполнена", как только внутренняя задача заканчивает начинаться. Когда вы используете WhenAll
, вы не заботитесь о том, когда внешняя задача заканчивается, вы заботитесь о том, когда , внутренние задача, заканчиваются. Есть много способов обращаться с этим. Нужно использовать , Разворачивают
.
Task t1 = Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
}).Unwrap();
Now you have your expected Task
and WhenAll
will take at least 2000 milliseconds, as expected. You could also add in another await
call to do the same thing:
Task t1 = await Task.Factory.StartNew(async() =>
{
await Task.Delay(2000);
return 2;
});
As mentioned by svick in a comment another option would be to just use Task.Run
instead of StartNew
. Task.Run
has a special set of overloads for methods that take a Func>
and return a Task
and automatically unwrap them for you:
Task t1 = Task.Run(async() =>
{
await Task.Delay(2000);
return 2;
});
Поэтому предпочтительно использовать Задачу. Управляемый
как опция по умолчанию, когда вы создаете async лямбды, поскольку это будет "обращаться" с этой проблемой для вас, хотя лучше знать о нем для сложных случаев, где вы не можете использовать Задачу. Управляемый
.
Наконец мы приходим к выбору, который вы не сделали, который является тем, что, вероятно, необходимо на самом деле делать в этом случае. Начиная с Задача. Задержка
уже возвращает Задачу, нет никакой потребности поместить его в StartNew
во-первых. Вместо того, чтобы создать вложенную задачу и использовать , Разворачивают
, вы не можете просто обернуть его во-первых:
var t3 = Task.Delay(3000);
await Task.WhenAll(t1, t2, t3);
Если вы на самом деле просто хотите ждать установленной суммы времени, это - то, что необходимо делать.