У меня есть несколько асинхронных методов, которые мне нужно вызвать и ждать их завершения. Асинхронные методы имеют параметры обратного вызова, которые выполняются при завершении асинхронной обработки. Поэтому я думаю, что мне нужно поставить какое-то сигнальное устройство в каждый обратный вызов, а затем дождаться появления всех сигналов перед продолжением.Подождите, пока несколько методов с обратными вызовами закончатся
После некоторого поиска я думаю, что могу использовать массив из AutoResetEvents
, а затем позвонить WaitHandle.WaitAll
, чтобы дождаться их. Что-то вроде:
WaitHandle[] waitHandles = new WaitHandle[]
{
new AutoResetEvent(false),
new AutoResetEvent(false)
};
DoWorkA((callback) =>
{
waitHandles[0].Set();
});
DoWorkB((callback) =>
{
waitHandles[1].Set();
});
// wait for DoWorkA and DoWorkB to finish
WaitHandles.WaitAll(waitHandles);
// continue with the processing
Я хотел бы знать, если это хороший способ сделать это, или если есть лучший/простой способ. Мне нужно решение для .Net 2.0, но мне также было бы интересно узнать, какие другие решения будут доступны с более поздней версией .Net.
EDIT: После попытки использования этого кода я обнаружил, что он не работает. Нить UI останавливается на WaitHandles.WaitAll(waitHandles)
и обратные вызовы никогда не закончатся ...
Внутри методов DoWork есть код время запуска asnychronously на фоне потока, а затем из этого фонового потока я пытаюсь запустить функцию обратного вызова через BeginInvoke
называемый на управление из потока пользовательского интерфейса. Однако обратный вызов никогда не запускается в потоке пользовательского интерфейса. Любые идеи, что я делаю неправильно?
EDIT 2: я понял, почему он не работает - поток вызова WaitHandles.WaitAll(waitHandles)
тот же поток, что обратные вызовы пытаются работать на (нить UI). Поэтому, конечно, если поток ожидает сигнала, обратные вызовы никогда не будут выполняться в этом же потоке, и поэтому Set()
никогда не будет вызван. WaitAll (waitHandles) и Set() должны работать, если они не предназначены для запуска в одном потоке. Я думаю, мне нужно исправить это, чтобы обратные вызовы выполнялись в фоновом потоке, пока поток пользовательского интерфейса ожидает. Пожалуйста, дайте мне знать, если мое мнение здесь неверно.
Благодарим за информацию об 4,5 (только для учебных целей). Тем не менее, я не могу переписать методы, которые я вызываю (DoWorkA, DoWorkB в примере), я должен их вызвать, так как мне нужно работать с их обратными вызовами ... Что касается использования семафора, та работа? – JPProgrammer
@JPProgrammer Семафор - начните с номера обратного вызова и подождите, ReleaseSemaphore в каждом обратном вызове, в результате исходный поток будет продолжаться, когда релиз называется number_of_callbacks раз. Async/wait: ознакомьтесь с http://stackoverflow.com/questions/15575579/rewriting-code-to-take-advantage-of-c-sharp-async-feature для повторного использования методов с обратными вызовами в мире async/wait. –