Реализация слушателя (подписка) в GUI с использованием асинхронных расширений - PullRequest
0 голосов
/ 02 января 2012

Это модель для трехслойного приложения с асинхронным ответом, который я пытаюсь использовать:

  • GUI
  • Back-end
  • Удаленный сервер

GUI:

private async void readFloatButton_Click(object sender, RoutedEventArgs e)
{
  FloatValueLabel.Content = (await srvProtocol.ReadFloat("ReadFloatX")).ToString();
}

Back-end (используются внутренние переменные binReader и соединение )

public Task<float> ReadFloat(string cmd)
 {
   var tcs1 = new TaskCompletionSource<float>();
   var floatTask = tcs1.Task;    
   RegisterResponse(cmd, 
                     () =>
                     tcs1.SetResult(_binReader.ReadSingle());
                    );
   // We are ready: now send request to server(assuming that this is a quick operation)
   connection.Send(cmd); 
   return floatTask;
 }

ЗдесьRegisterResponse добавляет пару в некоторый потокобезопасный словарь.Другой рабочий поток читает сообщения сетевого потока (заголовки сообщений) и вызывает действия в соответствии со строкой cmd, найденной в заголовке сообщения.

Теперь вопрос:

  • возможно лидостичь того же уровня краткости, когда мне нужно будет подписывать элементы графического интерфейса для периодических обновлений (не один обратный вызов)?

1 Ответ

1 голос
/ 02 января 2012

Ну, вы можете просто взять то, что у вас есть, и поместить в цикл, например:

private async void StartReading()
{
  while (true)
  {
    FloatValueLabel.Content = (await srvProtocol.ReadFloat("ReadFloatX")).ToString();
    await Task.Delay(1000);
  }
}

Хотя лично мне не нравится цикл "бесконечный асинхронный".Единственный способ остановить цикл - вызвать исключение (ошибка или отмена).

Библиотека Rx больше подходит для подписок.Он допускает высокий уровень «краткости», но имеет более крутой график обучения.

Вы также можете заключить всю логику подписки в Model / ViewModel.Это особенно имеет смысл при «обновлении» той же концептуальной ценности.В этом случае StartReading будет методом для вашей Model / ViewModel.Он будет использовать async (для бесконечного асинхронного цикла) или ObserveOn (для Rx), чтобы перенести обновления в поток пользовательского интерфейса, а затем использовать стандарт INotifyPropertyChanged / ObservableCollection для косвенного обновления пользовательского интерфейса.

...