2009-06-05 21 views
-1

Ich mache eine WPF-Anwendung und es ist auch ein WCF-Server, das Problem, das ich habe, ist, dass ich den ServiceHost öffnen muss und in einem Port für die Clients zu hören und Anfragen sobald annehmen es beginnt, aber das Problem, das ich habe, ist, dass, wenn ich den Code schreiben, um den Host host.open im Konstruktor nach der Funktion this.InitializeComponent() zu öffnen, schlägt es mit einer Ausnahme fehl. Wenn ich den Host in einem Button öffne und ich ihn nach dem Start der App drücke, funktioniert das ohne Probleme.C# WCF host.open fehlgeschlagen

Warum ist das und wie kann ich dieses Problem beheben?

Ich benutze einen tcp.net-Kanal, ich hosste es in der Anwendung und die Ausnahme, die ich erhalte, ist über den Service bereits registriert wurde.

Die Ausnahme auf den Clients ist:

inner exception message :"An existing connection was forcibly closed by the remote host"
error number: 10054
Socket error: System.Net.Sockets.SocketError.ConnectionReset

dank

Wally

der Konstruktor ist:

public Window1() 
{ 
    this.InitializeComponent(); 
    starthost(); 
} 

private void starthost() 
{ 
    host = new ServiceHost(typeof (Window1), 
          new Uri[]{ new Uri("net.tcp://localhost:8000") }); 

    host.AddServiceEndpoint(typeof(IGanador), new NetTcpBinding(), "Contador"); 
    host.open(); //it fails with this line here but not in a button 
} 
+0

Wie lautet Ihr Code? Wenn ich raten müsste, würde ich sagen, dass es so klingt, als würde man Code schreiben, so dass es zweimal läuft. – tomasr

+0

Ich fand heraus, dass System.ServiceModel meinen Konstruktor window1 aufruft, immer wenn es eine Client-Anfrage erhält, ist das ein Microsoft Bug? oder ist das das erwartete Verhalten? es macht einfach keinen Sinn für mich. –

+0

Nein, Sie haben wahrscheinlich den standardmäßigen "Pro-Call" -Instanzierungsmodus aktiviert. Das ist das erwartete Verhalten - jede Anfrage vom Client wird eine Instanz des Servers auslösen. –

Antwort

3

So bekomme ich das richtig? Ihr "Window1" ist eine WPF-Fensterklasse, die den Servicevertrag IGanador? Das scheint etwas seltsam zu sein. Wie wäre es mit einer eigenen Klasse, z. "GanadorService", der IContador implementiert? Dann würde diese CLASS für jede Anfrage erstellt/instanziiert werden - nicht Ihr Fenster.

public Window1() 
{ 
    this.InitializeComponent(); 
    starthost(); 
} 

private void starthost() 
{ 
    host = new ServiceHost(typeof (GanadorService), 
          new Uri[]{ new Uri("net.tcp://localhost:8000") }); 

    host.AddServiceEndpoint(typeof(IGanador), new NetTcpBinding(), "Contador"); 
    host.open(); //it fails with this line here but not in a button 
} 


public class GanadorService : IGanador 
{ 
    .... (whatever methods you need) ..... 
} 

Das sollte helfen, hoffe ich!

Marc

+0

Ich habe es so gemacht, weil ich die GUI ändern muss und ich nicht sicher war, wie ich ein Handle meines Fensters an die Klasse übergebe, die die Schnittstelle für den Servicehost implementiert. Weil ich den Konstruktor nicht aufruft, aber das ServiceModel tut es direkt. Gibt es einen Weg, das zu tun? Vielen Dank... –

0

Hallo
ich entschlossen das Problem dank viel auf die Kommentare von marc_s
ich ein singlenton Servicehost erstellt
Hinzufügen des folgenden Attribut meiner window1

[ServiceBehavior (InstanceContextMode = InstanceContextMode.Single)]

und vorbei dies im Konstruktor:

host = neue Servicehost ( dies, neue Uri [] { neue Uri ("net.tcp: // localhost: 8000});

es funktioniert super, weil ich ohnehin nur

dank einen Client
dies mit der Erklärung von WCF Instanz managment eine Verbindung mit einem großen Artikel ist:

http://msdn.microsoft.com/en-us/magazine/cc163590.aspx

0
  1. Bei der Verwendung von Nachrichtenvertragstyp als Parameter, Nur ein Parameter kann im Service verwendet werden

    [OperationContract] 
    void SaveEmployeeDetails(EmployeeDetails emp); 
    
  2. Servicebetrieb sollte entweder Messagetyp zurückgeben oder es sollte keinen Wert zurückgeben

    [OperationContract] 
    EmployeeDetails GetEmployeeDetails(); 
    
  3. Servicebetrieb akzeptiert und nur Nachricht Vertragsart zurückzukehren. Andere Datentypen sind nicht zulässig.

    [OperationContract] 
    EmployeeDetails ModifyEmployeeDetails(EmployeeDetails emp); 
    

Hinweis: Wenn eine Art sowohl Nachrichten- und Daten Vertrag hat, wird Service-Betrieb nur Nachrichtenvertrag akzeptieren.