Подождите, пока не будет вызван делегат

У меня есть асинхронный класс с методом StartProcessing(), который вызывает событие int ResultReady() после завершения обработки. StartProcessing() занимает очень мало времени.

Я хочу вызвать этот класс синхронно. Мой псевдокод должен быть примерно таким:

  1. Вызов StartProcessing()

  2. Ждать/спать, пока не будет готов результат

  3. Возвращаемый результат

Какой шаблон проектирования лучше всего подходит для этого? Не могли бы вы указать мне пример кода?


person Ilya Kogan    schedule 14.02.2011    source источник


Ответы (1)


Один из простых способов сделать это — использовать ManualResetEvent, который обработчик событий и код ожидания имеют доступ к ним. Вызовите Set из обработчика событий и < href="http://msdn.microsoft.com/en-us/library/58195swd.aspx" rel="noreferrer">WaitOne (или перегрузка с тайм-аутом) из ожидающего потока. Обратите внимание, что это невозможно сделать в потоке STA, поэтому вы не можете сделать это в потоке WinForms (который всегда должен быть STA), но в любом случае вы не должны ждать в потоке пользовательского интерфейса.

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

var async = new AsyncClass();
var manualEvent = new ManualResetEvent();
async.ResultReady += args => manualEvent.Set();
async.StartProcessing();
manualEvent.WaitOne();
person Jon Skeet    schedule 14.02.2011
comment
Когда я это делаю, кажется, что ResultReady никогда не вызывается. Я подозреваю, что делегат настроен на запуск в том же потоке, который заблокирован. Однако делегат в моем случае вызывается из структуры, которую я не контролирую. Следовательно, я никогда не получаю прохода WaitOne. Есть ли у вас какие-либо идеи о том, как это решить? - person dynamokaj; 02.10.2015
comment
@dynamokaj: Делегаты не настроены на запуск в каком-либо конкретном потоке. Используемый вами фреймворк может принять решение об инициировании события в определенном потоке... но в основном мы не можем вам помочь без дополнительной информации. Я предлагаю вам задать новый вопрос с более подробной информацией. - person Jon Skeet; 02.10.2015