C # .NET события и многопоточность - PullRequest
0 голосов
/ 11 августа 2010

Я занимаюсь разработкой приложения, которое разделено на несколько сборок .NET (один основной исполняемый файл и набор библиотек классов). В настоящее время я использую графический интерфейс WPF, но мне необходимо сохранить гибкость, чтобы в будущем переключиться на другую среду графического интерфейса.

Вот моя проблема: одна из библиотек классов выполняет некоторую работу в отдельном потоке и вызывает событие, когда этот поток завершается. Я быстро обнаружил, что мой WPF GUI расстроился, когда я попытался изменить его компоненты из этого обработчика событий, поэтому я реализовал «очередь событий», которая отправляет события в основной поток, используя System.Windows.Threading.DispatcherTimer. Это сделало работу; однако я с ужасом обнаружил, что этот DispatcherTimer работает только в контексте приложения WPF!

Я пытаюсь скрыть все уродливые детали многопоточности в этой библиотеке классов, которая может в конечном итоге использоваться вместе с графическим интерфейсом не-WPF. Идея состоит в том, что приложение-потребитель должно иметь возможность обновлять свой графический интерфейс из обработчиков событий. Итак, мой вопрос, есть ли стандартный метод (независимо от какой-либо конкретной структуры GUI) для вызова событий в другом потоке ??

Любая помощь будет оценена. Спасибо.

Ответы [ 4 ]

1 голос
/ 11 августа 2010

Обычно вы просто перенаправляете данные о событиях в основной поток, повторно вызывая обработчик событий из основного потока.Один метод показан ниже.

private void DispalyMessage(byte[] bytes)
{
  if (this.InvokeRequired)
  {
    lock (_lock)
    {
      EventHandler d = new EventHandler(DispalyMessage);
      this.Invoke(d, new object[] { bytes });
      return;
    }
  }
  else
  {
    //do something with the data
  }
}

Наслаждайтесь!

1 голос
/ 11 августа 2010

Вы можете использовать SynchronizationContext (это то, что делает BackgroundWorker, я полагаю) - или вы можете просто предупредить своих клиентов, что события будут возникать на фоне поток, и что они должны выполнять то, что им нужно (как другие API, такие как FileSystemWatcher.)

1 голос
/ 11 августа 2010

Вам необходимо использовать ISyncronizeInvoke . Этот интерфейс позволяет вам проверить, находитесь ли вы в правильном потоке, а если нет, вызвать метод в правильном потоке. Я не делал этого в WPF, но я предполагаю, что он реализован там же, как и Windows Forms.

0 голосов
/ 11 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...