Hier ist meine Situation. Ich habe einen WCF-Dienst geschrieben, der eine der Code-Basen unseres Anbieters aufruft, um Vorgänge wie Anmelden, Abmelden etc. auszuführen. Eine Voraussetzung für diesen Vorgang ist, dass wir einen Hintergrund-Thread haben, um Ereignisse als Ergebnis dieser Aktion zu erhalten. Beispielsweise wird die Login-Aktion für den Hauptthread gesendet. Dann werden mehrere Ereignisse von dem Vendor-Service als Ergebnis der Anmeldung zurück empfangen. Es können 1, 2 oder mehrere Ereignisse empfangen werden. Der Hintergrundthread, der auf einem Timer ausgeführt wird, empfängt diese Ereignisse und löst ein Ereignis im Dienst "wcf" aus, um zu benachrichtigen, dass ein neues Ereignis eingetroffen ist.WCF-Dienst mit Rückrufen aus dem Hintergrund Thread?
Ich habe den WCF-Dienst im Duplex-Modus implementiert und geplant, Callbacks zu verwenden, um der Benutzeroberfläche mitzuteilen, dass Ereignisse eingetroffen sind. Hier ist meine Frage: Wie sende ich neue Ereignisse aus dem Hintergrund-Thread an den Thread, der den Dienst ausführt?
Gerade jetzt, wenn ich OperationContext.Current.GetCallbackChannel<IMyCallback>()
aufrufen, ist der OperationContext null. Gibt es ein Standardmuster, um dies zu umgehen?
Ich benutze PerSession als meine SessionMode auf dem ServiceContract.
UPDATE: Ich dachte, ich würde mein genaues Szenario klarer machen, indem ich demonstriere, wie ich Ereignisse vom Verkäufercode empfange. Meine Bibliothek empfängt jedes Ereignis, bestimmt das Ereignis und löst ein Ereignis für dieses bestimmte Ereignis aus.
Ich habe ein anderes Projekt, das eine Klassenbibliothek speziell für die Verbindung mit dem Anbieter-Service ist. Ich werde die gesamte Implementierung des Dienstes veröffentlichen, ein klareres Bild zu geben:
[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
};
}
}
Das AgentEvent Objekt enthält den Rückruf als eine ihrer Eigenschaften, und ich dachte, dass ich den Rückruf wie folgt durchführen würde:
agentEvent.Callback = OperationContext.Current.GetCallbackChannel<ICallback>();
die AgentEvent ist ein Objekt im Dienst definiert:
0123:[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 wie folgt aussieht
public interface IVendorCallback
{
[OperationContract(IsOneWay = true)]
void SendEvent(AgentEvent agentEvent);
}
Der Rückruf wird auf dem Client implementiert und verwendet die EventArgs-Funktion des AgentEvent zum Auffüllen von Daten auf der Benutzeroberfläche. Wie würde ich die OperationContext.Current-Instanz vom Hauptthread in den Hintergrundthread übergeben?
Es gibt nicht genug Informationen in Ihrem Update, um wirklich zu verstehen, was vor sich geht. Wo befindet sich dieser Code? Wie machst du den "Login"? Ist es eine Art asynchrone Methode? Was passiert mit dem 'AgentEvent' (wo wird es eigentlich verwendet)? Und was ist der Typ von 'agentEvent.Callback' und wie/wann wird der Wert verwendet? – Aaronaught
Ich habe ein vollständigeres Beispiel von dem, was ich versuche, hinzugefügt. Die Ereignisse, die ich erhalte, werden von der Bibliothek ausgelöst, die ich innerhalb des Dienstes verwende, weshalb ich sie abonnieren muss. –