Я столкнулся с аналогичными проблемами, когда моя служба совершила асинхронный вызов на бизнес-уровне, а затем дождалась, когда событие вернется к службе. Когда событие было запущено, контекст обратного вызова был потерян. Я не вдавался в подробности о том, почему это так, но я закончил реализацию обходного пути, по существу хранящего ссылку на текущийконтекст, и отпустив отдельный поток, чтобы вызвать вызов бизнес-уровня, и после того, как он завершен, обратный вызов с помощью ссылка я сохранил.
1) Создайте новый класс, который будет содержать как мой запрос ввода, так и подтверждение для обратного вызова, например.
public struct MyCallbackDetails {
public MyCallbackDetails(IMyServiceCallback callback, RequestType request) : this()
Callback = callback;
Request = request;
}
public IMyServiceCallback Callback { get; set; }
public RequestType request { get; set; }
}
2) Тогда я бы выстрелить отдельную нить пропускании MyCallbackDetails объект, а не только по запросу:
public ResponseType MyServiceMethod(RequestType request) {
//...Do Some Stuff
//Create MyCallbackDetails object to store reference to the callback and keep channel open
MyCallDetails callDetails = new MyCallDetails(OperationContext.Current.GetCallbackChannel<IMyServiceCallback>(), request);
//Fire off a new thread to call the BL and do some work
Thread processThread = new Thread(RunCallbackMethod);
processThread.Start(callDetails);
}
3) И мой RunCallbackMethod бы сделать вызов BL и ответить на обратный вызов.
void RunCallBackMethod(Object requestDetails)
{
//Use callbackdetails to make BL calls
MyCallbackDetails callDetails = (MyCallbackDetails)requestDetails;
// Make BL call - all code under here is syncrhonous
ResponseType response = BusinessLayer.BusinessMethod(callDetails.Request);
//NB: If your responsetype is a business object you will need to convert it to a service object
callDetails.Callback.SomeMethod(results);
}
NB: Да я уже покончили с наличием события из моего бизнеса слой огня обратно в служебный слой, однако, как я стреляя отдельную нить для бизнеса слоя она по-прежнему работает в асинхронном режиме и выполняет те же функции как если бы я вызывал BL прямо в ASync и ожидал, когда событие сообщит о его завершении.
PS: Благодаря Rory за идею и большую часть кода для реализации этого.
Вы уверены, что сервис по-прежнему открыт, когда вы выполняете обратный вызов? – Gromer