2013-07-25 3 views
6

Ich bin neu in WCF. Ich mache einen Dienst, in dem ich eine langwierige Operation berechnen muss. Da die Methode lang ist, dachte ich, ich könnte die Operation async machen, indem ich eine Aufgabe zurücksende. Aber es funktioniert nicht. Ich bekomme immer noch eine Timeout-Ausnahme. Beispielcode (nicht meine eigentliche Code) zeigt mein Problem unter:WCF ServiceContract Methode, die Aufgabe <T> zurückgibt und Timeout

[ServiceContract] 
public interface ICalculator 
{ 
    [OperationContract] 
    Task<double> ComputePiAsync(ulong numDecimals); 
} 

internal class Calculator : ICalculator 
{ 
    public async Task<double> ComputePiAsync(ulong numDecimals) 
    { 
     return await SomeVeryVeryLongWayOfComputingPi(numDecimals); 
    } 
} 

// server 
using (var host = new ServiceHost(typeof(Calculator), new Uri("net.pipe://localhost"))) 
{ 
    host.AddServiceEndpoint(typeof(ICalculator), new NetNamedPipeBinding(), "Calculator"); 
    host.Open(); 

    Console.WriteLine("Service is running. Press <ENTER> to exit."); 
    Console.ReadLine(); 

    host.Close(); 
} 

// client 
var factory = new ChannelFactory<ICalculator>(new NetNamedPipeBinding(), new EndpointAddress("net.pipe://localhost/Calculator")); 
var calculator = factory.CreateChannel(); 
await calculator.ComputePiAsync(numDecimals); // <--- this call takes longer than 1 minute and I'm getting a timeout here. 

Also, was soll ich tun, um eine langwierige Operation an meinem Dienst zu rufen und asynchron auf das Ergebnis warten? Timeout erhöhen? Wenn ich das Zeitlimit für Vorgänge heraufsetze, was bringt es dann, wenn die Methode eine Aufgabe zurückgibt?

Antwort

12

Da das Verfahren ist langwierig Ich dachte, ich async

Halten Sie auf den Betrieb machen könnte, verlangsamen - Sie mischenAsynchronität mit Netzbetrieb Timeout auf.

Lets Asynchronität betrachten zuerst:

1. Mit async/await-asynchron Anruf eines WCF-Dienst von Client

async/await auf Client-Seite hilft uns asynchrones Programm zu schreiben, so dass die Anwendung bleibt responsive - im Fall von beispielsweise WPF/WinForm möchten wir die Benutzeroberfläche nicht durch einen synchronen Aufruf eines WCF-Dienstes im UI-Thread einfrieren. Stattdessen können wir es asynchron mit async/await nennen. Die Magie hier ist, dass dies vollständige clientseitige Funktionalität ist - was bedeutet, dass der Dienst nicht asynchron sein muss oder keine Task zurückgeben - alles, was Sie tun müssen, ist beim Erstellen der müssen Sie Visual Studio zu Task basierten asynchronen Operationen generieren - und Sie Verwenden Sie dann async/await auf Ihrem Client.

2. Dann Was ist die Notwendigkeit für async/await auf der Service-Seite?

Der Dienst selbst kann einige I/O wie Abfrage einige Datenquelle oder in-turn-Aufruf eines anderen Dienstes durchführen. Durch die Verwendung async/await auf der Dienstseite - der Dienst kann diese Vorgänge asynchron ausführen - ohne Service-Threads zu blockieren. Das bedeutet, dass der Dienst mehr freie Threads hat, um neue Clients zu bedienen - daher skaliert der Dienst viel besser.

nun über zwei sollte nicht mit lange Lauf Servicebetrieb

verwechseln Wenn Ihr Dienst dauert lange um Ergebnisse zu erhalten, können Sie es zu tun haben mit Netzwerk Timeouts. Sie können und sollten nicht versuchen, eine Netzwerkverbindung unbegrenzt offen zu halten, ohne dass etwas passiert. WCF hilft Ihnen dabei, verschiedene Timeouts zu konfigurieren. Wenn Ihre Service-Methode lange braucht, um sie zu beantworten, müssen Sie diese Zeitüberschreitungen erhöhen. Sie können die Verwendung von WCF callback contracts in Erwägung ziehen, wenn Sie den Fortschritt an den Client zurückmelden möchten.Wenn dies nicht Ihren Anforderungen entspricht, müssen Sie Ihren Dienst so umgestalten, dass der Client den lang andauernden Prozess einleiten und anschließend eine andere Methode des Dienstes aufrufen kann, um den Status abzufragen.

+3

+1. Um auf den letzten Punkt hinzuweisen, kehrt 'async' auf der Serverseite nicht * früher zum Client * zurück. Die Antwort wird erst an den Client gesendet, wenn die zurückgegebene Aufgabe abgeschlossen ist. –

+1

@ StephenCleary: Danke. Ja, Service-Seite Async/Warte-Asynchronität ist für den Client nicht sichtbar. – YK1

+0

Wertvolle Frage und gute, klare Antwort. Wenn der Anruf lange dauert, weil die Operation am Dienst viel Rechenzeit erfordert, bin ich mir nicht sicher, ob ich darauf verweisen würde, was zu einem Netzwerk-Timeout führen würde. Ich stelle mir vor, diese beziehen sich auf Senden/Empfangen Timeouts, während eine Operation Timeout bezieht sich auf diese + Rechenzeit? –

0

Zuerst müssen Sie sicher sein, dass das Problem wirklich der Async-Aufruf ist. Versuchen Sie, Ihren Dienst synchron aufzurufen, um zu sehen, ob der Aufruf erfolgreich ausgeführt wird.

Angenommen, Ihr Problem ist in der Tat die asynchrone Operation, Sie sollten die WCF IAsyncResult anstelle von async verwenden, da dies die Standardbehandlung von asynchronen Operationen in WCF ist. Sie benötigen eine Operation, um den Service zu starten, und eine weitere, um die Ergebnisse zu verarbeiten.

Ich konnte einige Code schreiben, aber hier sind einige gute Beiträge, die meinen Standpunkt ausführlich erläutern und sind lesenswert:

Noch ein Tipp:

nach diesen Schritten, wenn Sie feststellen, dass der Kunde mehr Zeit benötigen, die async Ausführung zu verarbeiten, sollten Sie die operation timeout zu erhöhen, um eine länger warten auf die Rückkehr zu ermöglichen. Wenn die -Verbindung instabil ist, sollten Sie in Betracht ziehen, die open timeout auf zu erhöhen, um dem Client mehr Zeit zum Herstellen der Verbindung zu geben.

Ich hoffe, es hilft.

Verwandte Themen