Я столкнулся с подобными проблемами, когда моя служба выполняла асинхронный вызов на бизнес-уровне, а затем ожидала, пока событие не запустится в службе. Всякий раз, когда происходило событие, контекст обратного вызова терялся. Я не углубился в детали того, почему это так, но в итоге я реализовал обходной путь по существу хранения ссылки на currentcontext и запуска отдельного потока для вызова бизнес-уровня для вызова, и как только он завершится, вызовите обратный вызов с помощью ссылка, которую я сохранил.
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: Спасибо Рори за идею и большую часть кода для ее реализации.