C # .NET 3.5: как вызвать обработчик события и дождаться его завершения - PullRequest
4 голосов
/ 24 февраля 2009

У меня есть класс, содержащий рабочий поток, который получает данные из очереди в цикле.

Другая часть приложения получает событие из этого класса, которое класс вызывает для каждого элемента очереди.

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

Это должно быть хорошо, но мы обнаружили сценарий, в котором это может вызвать проблемы.

Нам нужно быстрое решение, пока решается основная проблема. Предоставляет ли фреймворк простой способ заставить рабочий поток ждать, пока обрабатывается каждое событие (чтобы они обрабатывались последовательно)? Если нет, то как проще всего это осуществить?

Ответы [ 6 ]

4 голосов
/ 24 февраля 2009

Простой ответ - заблокировать () для одного объекта в обработчике событий. Все жабы будут ждать, чтобы получить замок.

3 голосов
/ 24 февраля 2009

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

1 голос
/ 26 февраля 2009

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

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
1 голос
/ 24 февраля 2009

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

События AFAIK будут асинхронными, и я не знаю каких-либо «простых» способов изменить это.

0 голосов
/ 24 февраля 2009

Все события обработки событий обработчиков событий, вызванные рабочим потоком чтения очереди, вызываются в рабочем потоке чтения очереди. Пока обработчики событий не порождают свои собственные потоки, вы должны иметь возможность ждать завершения обработчиков событий, вызывая Thread.Join () в рабочем потоке чтения очереди.

0 голосов
/ 24 февраля 2009

Нет общего пути.

В конце обработчики должны предоставить механизм для отслеживания.

Если вы используете BeginInvoke, а не вызываете события напрямую, вы можете использовать оболочку, в которой вы вызываете реальный обработчик событий синхронно, а затем вызывать оболочку асинхронно. Оболочка может поддерживать счетчик (с блокированными операциями) или устанавливать событие в соответствии с вашими потребностями.

Что-то вроде:

TheDelegate realHandler = theEvent;
var outer = this;
ThreadPool.QuereUserWorkItem(x => {
  // Set start of handler
  realHandler(outer, eventArgs);
  // Set handler finished
};
...