Oto moja sytuacja. Napisałem usługę WCF, która wywołuje jedną z baz kodu dostawcy naszego dostawcy, aby wykonywać operacje, takie jak logowanie, wylogowanie itp. Warunkiem tej operacji jest posiadanie wątku tła w celu odbierania zdarzeń w wyniku tej akcji. Na przykład akcja logowania jest wysyłana w głównym wątku. Następnie, w wyniku logowania, zostaje odebranych kilka zdarzeń z usługi dostawcy. Może być odebranych 1, 2 lub kilka zdarzeń. Wątek tła działający na czasomierzu odbiera te zdarzenia i uruchamia zdarzenie w usłudze wcf, powiadamiając o nadejściu nowego zdarzenia.Usługa WCF z wywołaniami zwrotnymi pochodzącymi z wątku tła?
Zaimplementowałem usługę WCF w trybie dupleksu i zaplanowałem używanie wywołań zwrotnych do powiadamiania interfejsu użytkownika o nadchodzących zdarzeniach. Oto moje pytanie: Jak wysłać nowe zdarzenia z wątku tła do wątku, który wykonuje usługę?
Teraz, gdy zadzwonię pod numer OperationContext.Current.GetCallbackChannel<IMyCallback>()
, operacja Kontekst jest pusta. Czy istnieje standardowy wzorzec do obejścia tego?
Używam PerSession jako mój SessionMode na ServiceContract.
AKTUALIZACJA: Pomyślałem, że przedstawię dokładniejszy scenariusz, demonstrując, w jaki sposób odbieram zdarzenia z kodu dostawcy. Moja biblioteka odbiera każde zdarzenie, określa, czym jest zdarzenie, i odpala zdarzenie związane z tym konkretnym wydarzeniem.
Mam inny projekt, który jest biblioteką klasy specjalnie do połączenia z usługą dostawcy. wyślę całą realizację usługi w celu uzyskania jaśniejszego obrazu:
[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
};
}
}
Przedmiotem AgentEvent zawiera zwrotnego jako jednego z jego właściwości, a ja myślałem, że ja wykonać zwrotnego tak:
agentEvent.Callback = OperationContext.Current.GetCallbackChannel<ICallback>();
AgentEvent to obiekt zdefiniowany w serwisie:
[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 wygląda następująco:
public interface IVendorCallback
{
[OperationContract(IsOneWay = true)]
void SendEvent(AgentEvent agentEvent);
}
Callback jest zaimplementowany na kliencie i wykorzystuje porporty EventArgs w AgentEvent do zapełnienia danych w interfejsie użytkownika. Jak przekazać wystąpienie OperationContext.Current z wątku głównego do wątku tła?
W aktualizacji brakuje wystarczających informacji, aby naprawdę zrozumieć, co się dzieje. Gdzie znajduje się ten kod? Jak wykonać "logowanie"? Czy jest to jakaś metoda asynchroniczna? Co się dzieje z tym "AgentEvent" (gdzie właściwie jest używany)? A jaki jest typ 'agentEvent.Callback' i jak/kiedy jest używana jego wartość? – Aaronaught
Dodałem pełniejszy przykład tego, co próbuję zrobić. Wydarzenia, które otrzymuję, są uruchamiane z biblioteki, której używam w ramach usługi, dlatego muszę je zasubskrybować. –