2015-07-21 2 views
1

У меня есть задача, которая работает в Form_Load случае UserControl в WinForms:Task вызывает странное поведение в случае Form_Load

private void ucDeviceInsert_Load(object sender, EventArgs e) 
    { 
     System.Threading.Tasks.Task getTBox = System.Threading.Tasks.Task.Run(async() => 
     { 
      await AVeryLongRunningProccess(); 
     }); 

     pbImage.Image = Properties.Resources.Remove; 

     getTBox.Wait(); 

     pbImage.Image = Properties.Resources.Insert; 

     btnNext.Visible = true; 

     tmrDeviceInsert.Enabled = true; 
     tmrDeviceInsert.Start(); 
    } 

private void tmrDeviceInsert_Tick(object sender, EventArgs e) 
    { 
     Next(); 
    } 

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

+1

Кстати, создание 'getTBox' может быть упрощено до' var getTBox = AVeryLongRunningProccess(); ' – Jacob

+1

@Jacob no, что изменило бы поведение, первая синхронная часть' AVeryLongRunningProccess' будет запущена в потоке пользовательского интерфейса , 'var getTBox = Task.Run (() => AVeryLongRunningProccess())' будет упрощенной версией. –

+0

Это правда, но если он скоро переходит в асинхронный, то этого должно быть достаточно. Вы правы, что если на фронте есть какой-то синхронный процессорный материал, это не будет нужным. – Jacob

ответ

2

Task.Run предназначен для отжимания ресурсоемкие работы от UI нить. Поскольку вы вызываете асинхронный метод, я подозреваю, что он не требует интенсивного использования ЦП.

Таким образом, вы можете просто использовать async и await:

private async void ucDeviceInsert_Load(object sender, EventArgs e) 
{ 
    pbImage.Image = Properties.Resources.Remove; 
    await AVeryLongRunningProccess(); 
    pbImage.Image = Properties.Resources.Insert; 
    btnNext.Visible = true; 
    tmrDeviceInsert.Enabled = true; 
    tmrDeviceInsert.Start(); 
} 

Обратите внимание, что в await, пользовательский интерфейс отображается, и пользователь может взаимодействовать с ним (это точка).

0

getTBox.Wait() попытается выполнить эту задачу синхронно. Поэтому остальная часть кода после этого не произойдет до после задача завершена.

Я думаю, что вы не хотите, чтобы ваша задача работать синхронно на всех, а обрабатывать ее завершение асинхронно, что-то вроде этого:

getTBox.ContinueWith(() => updateStatusInUI()); 
+1

Вы действительно [не должны смешивать ContinueWith] (http://blog.stephencleary.com/2013/10/continuewith-is-dangerous -too.html) с помощью async/wait. просто сделайте обработчик события 'Load' async и подождите' getTBox' –

+0

Не сделали winforms через некоторое время. Это определенно лучше, если поддерживается! – Jacob

+0

Единственная причина, по которой поддерживается 'async void', заключается в том, что вы можете использовать async с обработчиками событий, которые были созданы до того, как был изобретен асинхронный/ожидаемый. –

Смежные вопросы