2016-08-10 2 views
1

Я новичок в Winforms, поступающих из Интернета, и я пытаюсь настроить асинхронные вызовы.Winforms асинхронная задача, запускать несколько потоков одновременно без блокировки UI

У меня есть раскрывающийся список, который я бы назвал некоторыми методами для обновления 3 вкладок на моей странице. Я хотел бы сделать это асинхронно, чтобы он не блокировал пользовательский интерфейс и не помещал сообщение «Загрузка ...» на каждой вкладке и загружал их независимо друг от друга, при этом пользователь мог еще щелкнуть каждую вкладку и см. ход загрузки.

У меня есть следующее, однако это все еще блокирует пользовательский интерфейс, может ли кто-нибудь указать мне в правильном направлении, где я ошибаюсь?

Это мой выпадающий обработчик события

private async void ddlRoles_SelectedIndexChanged(object sender, EventArgs e) 
    { 
     await Task.Run(async() => 
     { 
      await setTab1(); 
     }); 

     await Task.Run(async() => 
     { 
      await setTab2(); 
     }); 

     await Task.Run(async() => 
     { 
      await setTab3(); 
     }); 
    } 

Это пример одного из моих задач, которые я хотел бы работать асинхронно.

private async Task setTab1() 
    { 
     if (tabl1Panel.InvokeRequired) 
     { 
      this.Invoke(new MethodInvoker(async delegate() 
      { 
       await setTab1(); 
      })); 
      return; 
     } 

     // LONG RUNNING CODE HERE... 
    } 
+0

@x ... нет, это не тот. Рекурсия не вызывает проблем с пользовательским интерфейсом. В ожидании задачи в потоке пользовательского интерфейса, которая сама пытается запустить код в уже заблокированном потоке пользовательского интерфейса (с помощью Invoke), является проблема –

+1

Не используйте потоки, вы вряд ли будете заниматься интенсивной работой с ЦП. Слово «Загрузка» означает, что вы выполняете операции ввода-вывода, и в этом случае вы должны выполнять асинхронный одиночный поток. – Aron

ответ

2

Командлет Invoke называют используется для запуска setTab1() означает, что код выполняется в потоке пользовательского интерфейса, следовательно, почему интерфейс блокируется.

Попробуйте сделать как можно больше внутри setTab1() без использования Invoke() и используйте Invoke() для запуска кода для обновления пользовательского интерфейса после того, как у вас есть все необходимые данные.

+0

Хорошо ... так вы говорите для каждой вкладки, выполняйте как можно большую часть работы в отдельном асинхронном методе без вызова, а затем вызываете отдельный метод обновления пользовательского интерфейса после его завершения? – user3284707

+2

@ user3284707 Вот что говорится в каждом руководстве и руководстве. Простейшим примером является, например, «var result = wait someHeavyFunc(); updateUi(); '. Если вы хотите публиковать регулярные обновления обновления, используйте 'IProgress ' и 'Progress ' реализация для отправки сообщений из задачи в UI –

+0

Большое спасибо, я посмотрю, смогу ли я это сделать :) – user3284707