Могу ли я получить контекст потока пользовательского интерфейса при использовании 'async / await'

Вы должны спросить себя, нужно ли вам общее решение ( другое - Аллен Браун ), или если вам это нужно только для этой цели. Если вы действительно нуждаетесь в этом только один раз, сделайте это простым способом.

На стороне примечания, при объединении списков в коде VBA, воспользуйтесь трюком, которым меня научил давний гуру доступа Trevor Best , и это нужно придерживать разделитель в начале каждого значения, а затем использовать Mid (), чтобы отключить его. Вместо этого внутри вашей петли через дочерние записи:

  If Len(strOutput) = 0 Then
     strOutput = NewValue
  Else
     strOutput = strOutput & ", " & NewValue
  End If

... используйте это внутри цикла:

  strOutput = strOutput & ", " & NewValue

... и затем, когда вы выходите из цикла , отделите главный разделитель:

  strOutput = Mid(strOutput, 3)

Это имеет последствия повсюду и упрощает код для конкатенации во множестве контекстов.

0
задан Bharathi 18 January 2019 в 03:05
поделиться

3 ответа

Вы завершили свой async вызов в задании. Это побеждает всю машину состояний и заканчивается ненужным использованием потока потоков.

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

Как минимум, вы должны делать это, если вам абсолютно необходимо использовать async void это просто ожидание задачи, а не ее завершение

private async void ActivateAsyncTicToc()
{
   try
   {
      IsTimerStartAsync = !IsTimerStartAsync;    
      await AsyncTicToc();
   }
   catch (Exception e)
   {
      // make sure you observe exceptions in async void
   }
}

Еще лучше, пусть async распространяется с использованием async Task

private async Task ActivateAsyncTicToc()
{
   IsTimerStartAsync = !IsTimerStartAsync;    
   await AsyncTicToc();
}

Что в любом случае выглядит подозрительно, вы, вероятно, должны быть делая это (Eliding async и await) и просто передавая задачу кому-то еще, кто будет ждать. это небольшой прирост производительности

private Task ActivateAsyncTicToc()
{
   IsTimerStartAsync = !IsTimerStartAsync;    
   return AsyncTicToc();
}

на самом деле это минное поле, и я буду здесь весь день

Вы должны начать читать о async и await

]
0
ответ дан Michael Randall 18 January 2019 в 03:05
поделиться

Прежде всего, вы можете использовать await Task.Delay(10) вместо Thread.Sleep(10) и изменить свой метод AsyncTicToc на async Task без запуска потока. Это сделает изменение элемента управления в потоке пользовательского интерфейса (контекст, от которого вы ожидали).

Во-вторых, чтобы обновить пользовательский интерфейс из других потоков, если вы не хотите использовать диспетчер напрямую, вы можете использовать абстракцию над ним: класс SynchronizationContext . См. Больше информации здесь .

Пример: SynchronizationContext.Current.Post(action, actionParameter);

В-третьих, более уместно использовать модель представления и привязку. Если вы используете WPF, он синхронизирует потоки для изменений свойств для вас.

0
ответ дан haimb 18 January 2019 в 03:05
поделиться

В то время как есть возможность «выйти» из другого потока в поток пользовательского интерфейса, используя Dispatcher или SynchronizationContext, я настоятельно рекомендую этого не делать. Это потому, что это делает вашу логику менее тестируемой и более привязанной к ее среде. В случае Dispatcher он сильно привязан к работе в среде WPF; SynchronizationContext лучше, но он все еще привязан к работе в какой-то среде.

При таком подходе у вас есть зависимость от вашей логики до потока пользовательского интерфейса, например:

Код пользовательского интерфейса => фоновая логика потока => Поток пользовательского интерфейса

Вместо этого используйте IProgress<T> и Progress<T> из фоновой логики потока, чтобы сообщать отчеты о ходе выполнения своему вызывающему, который решает, как отображать эти отчеты о ходе выполнения. Тогда ваша зависимость выглядит следующим образом:

UI code => логика фонового потока

и ваша логика фонового потока не зависит от наличия потока UI. Это делает его более убедительным и более тестируемым.

0
ответ дан Stephen Cleary 18 January 2019 в 03:05
поделиться
Другие вопросы по тегам:

Похожие вопросы: