Вот моя ситуация. Я написал службу WCF, которая вызывает одну из кодовых баз нашего поставщика для выполнения таких операций, как вход в систему, выход из системы и т. Д. Требование этой операции состоит в том, что у нас есть фоновый поток для получения событий в результате этого действия. Например, действие «Вход в систему» отправляется в основной поток. Затем несколько событий получаются обратно от поставщика услуг в результате входа в систему. Может быть получено 1, 2 или несколько событий. Фоновый поток, который запускается по таймеру, получает эти события и запускает событие в службе wcf, чтобы уведомить о прибытии нового события.
Я реализовал службу WCF в дуплексном режиме и планировал использовать обратные вызовы для уведомления пользовательского интерфейса о прибытии событий. Вот мой вопрос: как отправить новые события из фонового потока в поток, выполняющий службу?
Прямо сейчас, когда я вызываю OperationContext.Current.GetCallbackChannel<IMyCallback>()
, OperationContext имеет значение null. Есть ли стандартная схема, чтобы обойти это?
Я использую PerSession в качестве SessionMode для ServiceContract.
UPDATE:
Я думал, что проясню свой точный сценарий, демонстрируя, как я получаю события из кода вендора. Моя библиотека получает каждое событие, определяет, что это за событие, и запускает событие для этого конкретного события.
У меня есть другой проект, который представляет собой библиотеку классов специально для подключения к службе поставщика. Я опубликую всю реализацию сервиса, чтобы дать более четкую картину:
[ServiceBehavior(
InstanceContextMode = InstanceContextMode.PerSession
)]
public class VendorServer:IVendorServer
{
private IVendorService _vendorService; // This is the reference to my class library
public VendorServer()
{
_vendorServer = new VendorServer();
_vendorServer.AgentManager.AgentLoggedIn += AgentManager_AgentLoggedIn; // This is the eventhandler for the event which arrives from a background thread
}
public void Login(string userName, string password, string stationId)
{
_vendorService.Login(userName, password, stationId); // This is a direct call from the main thread to the vendor service to log in
}
private void AgentManager_AgentLoggedIn(object sender, EventArgs e)
{
var agentEvent = new AgentEvent
{
AgentEventType = AgentEventType.Login,
EventArgs = e
};
}
}
Объект AgentEvent содержит функцию обратного вызова в качестве одного из своих свойств, и я думал, что выполню функцию обратного вызова следующим образом:
agentEvent.Callback = OperationContext.Current.GetCallbackChannel<ICallback>();
AgentEvent - это объект, определенный в сервисе:
[DataContract]
public class AgentEvent
{
[DataMember]
public EventArgs EventArgs { get; set; }
[DataMember]
public AgentEventType AgentEventType { get; set; }
[DataMember]
public DateTime TimeStamp{ get; set; }
[DataMember]
public IVendorCallback Callback { get; set; }
}
IVendorCallback выглядит так:
public interface IVendorCallback
{
[OperationContract(IsOneWay = true)]
void SendEvent(AgentEvent agentEvent);
}
Обратный вызов реализован на клиенте и использует свойство EventArgs AgentEvent для заполнения данных в пользовательском интерфейсе.
Как передать экземпляр OperationContext.Current из основного потока в фоновый поток?