Продолжение начинается до завершения задачи.
У меня есть следующий код в C#, VS2012, WPF 4.5. Я ожидаю, что .ContinueWith
будет выполнен после того, как задача будет полностью завершена (это и есть цель продолжения, не так ли?).
Это должно привести к значению 2 в finalResult
,
int myTestInt = 0;
Task task = Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
}).ContinueWith(_ =>
{
int finalResult = myTestInt;
});
По факту, finalResult
вместо этого присваивается значение 1. Так что похоже, что продолжение начато на await
заявление уже.
Это предполагаемое поведение? Я что-то здесь упускаю? Я не могу положиться на ContinueWith
начать после того, как задача полностью завершена?
Обновить:
Ответ Джастина просто вдохновил меня проверить следующее:
int myTestInt = 0;
Task task=Task.Factory.StartNew(async () =>
{
myTestInt = 1;
await Task.Delay(TimeSpan.FromSeconds(6));
myTestInt = 2;
});
task.Wait();
int result2 = myTestInt;
finalResult по-прежнему установлен в 1. Нет ли способа надежно ждать задачи, которая содержит await
с завершить?
3 ответа
Когда вы передаете async
делегировать Task.Factory.StartNew
, вернулся Task
представляет только первую часть этого делегата (до await
что-то, что еще не завершено).
Однако, если вы передадите async
делегировать в новый Task.Run
метод (который был включен по этой причине), возвращаемый Task
представляет весь делегат. Так что вы можете использовать ContinueWith
как вы ожидаете. (Хотя await
обычно лучший вариант, чем ContinueWith
).
Для получения дополнительной информации о StartNew
против Run
см . пост Стивена Туба по теме.
Ожидание немедленно вернет управление вызывающей функции, которая в этом случае является StartNew вашей задачи. Это означает, что задача будет затем завершена и выполнит ContinueWith. Если вы действительно хотите, чтобы задача была выполнена до ContinueWith, не ждите Task.Delay.
Я видел это в MSDN::-)
public async void button1_Click(object sender, EventArgs e)
{
pictureBox1.Image = await Task.Run(async() =>
{
using(Bitmap bmp1 = await DownloadFirstImageAsync())
using(Bitmap bmp2 = await DownloadSecondImageAsync())
return Mashup(bmp1, bmp2);
});
}
Так что не забывайте "async ()"!!!