Многопоточная синхронизация с использованием блокировки широкого диапазона с обратными вызовами WCF
Что я хочу сделать, так это
Я хочу сделать прокси-вызов для службы и получить данные в отдельном потоке с помощью асинхронного обратного вызова... сложная часть заключается в том, что я хочу, чтобы основной поток спал, пока все данные не будут получены.
Причина, по которой я не использую синхронный метод для этого, заключается в том, что я создаю API для службы WCF, которая использует пейджинг и возвращает данные порциями.
Я хочу, чтобы мой клиент мог использовать пейджинг, но я не хочу предоставлять все свои обратные вызовы пейджинга моему API... Я хочу, чтобы это выглядело так, как будто API предоставляет синхронный метод извлечения данных.
Я попытался использовать закрытый статический семафор (потому что он не зависит от потоков), который доступен для методов класса и обратных вызовов, с возможностью использования одной единицы в качестве средства для приостановки выполнения.
Сначала я использую оператор Semaphore.WaitOne().
Затем я выполняю вызов Proxy в потоке переднего плана, и служба создает поток, который обрабатывает извлечение данных, и управление передается обратно клиенту.
В клиенте я немедленно использую второй оператор Semaphore.WaitOne(). Это должно приостановить выполнение потока переднего плана, что он и делает. Затем, когда обратный вызов "Paging Completed" выполнен в отдельном потоке, я использую Semaphore.Release(). Но поток переднего плана никогда не пересекает второй оператор Semaphore, он остается заблокированным, и поэтому клиент зависает.
Есть идеи, что я делаю неправильно, или есть другой дизайн блокировки, который был бы более эффективным?
1 ответ
Если вы пытаетесь добиться того, чтобы поток переднего плана ждал потока сбора данных, вы можете рассмотреть возможность использования Задач, которые позволят вам легко выполнить то, что вы здесь описали.
System.Threading.Tasks: http://msdn.microsoft.com/en-us/library/dd235608.aspx
Некоторый код:
Task t = new Task(somethingToDo);
// Fire off the new task
t.Start();
// Wait for the task to finish...
t.Wait();
// Do something else...
Обязательно ознакомьтесь с деталями t.Wait() в документации. Есть некоторые исключения, к которым вы захотите быть готовыми в случае сбоя вашей задачи.