Разбираюсь в async/await. Вот такой код в WinForms (чтобы был UI-контекст):
private async void Parent(){
Write("Parent() start.");
var context = SynchronizationContext.Current;
Task task = Task.Run(()=>ChildAsync(context));
while (!task.IsCompleted)
{
Write("loop");
await Task.Delay(1000);
}
Write("Parent() done.");
}
private async Task ChildAsync(SynchronizationContext context)
{
await Task.Delay(3000);
}
public void Write(string message){
richTextBox1.AppendText($"\n{message}");
}
Почему в коде метода ChildAsync
вызов функции Write()
мешает дальнейшему выполнение кода, но при этом не мешает задаче завершиться (ведь сообщение Parent() done.
появляется):
При этом если Write()
вызвать после await
, то это не мешает выполнению задачи:
И еще меня сильно смущает, что программа выводит сообщение "loop" хотя бы один раз - если Write()
вызывает эксепшен и завершает задачу, то почему программа все же один раз входит в цикл?
Изменение задержки не помогает:
private async void Parent(){
Write("Parent() start.");
var context = SynchronizationContext.Current;
Task task = Task.Run(() => ChildAsync(context));
while (!task.IsCompleted)
{
await Task.Delay(5000);
Write("loop");
}
Write("Parent() done.");
}
private async Task ChildAsync(SynchronizationContext context)
{
Write(".......ChildAsync() done.");
context.Post((x) => Write(".......ChildAsync() done"), null);
await Task.Delay(3000);
}
Заключил код по созданию task'a в try-catch, но он не ловит ошибку. Почему?
private async void Parent(){
Write("Parent() start.");
var context = SynchronizationContext.Current;
Task task = null;
try
{
task = Task.Run(() => ChildAsync(context));
}
catch (Exception e)
{
MessageBox.Show(task.Exception.InnerException.Message);
}
while (!task.IsCompleted)
{
await Task.Delay(1000);
Write("loop");
}
Write("Parent() done.");
}
Вы, наверное, думаете, что эксепшон в таске должен выкидывать вас из цикла. Нет, тот эксепшон остается в таске (если вы не делаете await mytask
), то есть раз в основном потоке вы успели зайти в цикл, то код в цикле выполнится, хоть час ждите. Вот если вы await Task.Delay(5000);
поставите перед циклом while, а не внутри цикла, то тогда да, в цикл не попадете, за 5 сек таск успеет упасть
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Нужно создать окно для эффекта водяного знака на экранеВывести его поверх других окон и задать прозрачность получилось, но все события клика...
Настроил IIS на аутентификацию по смарт-карте по данной статье https://blogjayway
Нужно, чтобы значения из массива всегда выводились в случайном порядкеПробовал array_rand, но эта функция перемешивает только ключи массива