2016-05-13 11 views
0

In meinem Dienst habe ich derzeit einige Aufgaben und eine ReportProgress-Methode, die ständig eine Liste aktualisiert. Wie kann ich diese Liste an meine Client-Host-Anwendung zurückgeben?C# - Fortschritt von WCF Rest Service

Serviceseite:

public async void BeginSync(string dbId) 
{ 
    var progressIndicator = new Progress<string>(ReportSyncProgress); 
    var output = await BeginSyncTaskAsync(dbId, progressIndicator);        
} 

... in der Aufgabe, die ich einen Fortschrittsbericht in einer Schleife haben:

while ((output = process.StandardOutput.ReadLine()) != null) 
{ 
    progress.Report(output);   
} 

... und hier ist mein Bericht Methode:

public void ReportSyncProgress(string value) 
{ 
    // report by appending to global list 
    progressOutput.Add(value); 
} 

progressOutput ist eine Liste und ich brauche meinen Client, um in Echtzeit zu erhalten, wie es aktualisiert wird.

Vielen Dank!

+0

Sie haben uns Ihre Anforderungen mitgeteilt, Sie haben uns nie gesagt, welches Problem Sie haben, um diese Anforderungen zu erfüllen. Haben Sie schon einmal [WCF-Callback-Methoden] (https://adamprescott.net/2012/08/15/a-simple-wcf-service-callback-example/) angeschaut? –

+0

Das Problem ist, ich weiß nicht, wie man den Fortschritt zurückgibt, wie es aktualisiert wird. Ich habe Callback-Methoden noch nicht untersucht. – siegs

+0

Wie machen Sie einen Rückruf über einen Rest-Service? – siegs

Antwort

1

Da Ruhedienste keine Sitzungen haben, können Sie keine normale WCF-Rückrufmethode erstellen. Stattdessen müssen Sie eine Art Token übergeben und dann dieses Token verwenden, um die Fortschrittsinformationen zu erhalten.

private static ConcurrentDictionary<Guid, ConcurrentQueue<string>> _progressInfo; 

//You should never do "async void" WCF can handle using tasks and having Async suffixes. 
//see https://blogs.msdn.microsoft.com/endpoint/2010/11/12/simplified-asynchronous-programming-model-in-wcf-with-asyncawait/ 
public async Task BeginSyncAsync(string dbId, Guid progressKey) 
{ 
    if (!_progressInfo.TryAdd(progressKey, new ConcurrentQueue<string>())) 
    { 
     throw new InvalidOperationException("progress key is in use"); 
    } 

    var progressIndicator = new Progress<string>((value) => ReportSyncProgress(value, progressKey)); 
    try 
    { 
     var output = await BeginSyncTaskAsync(dbId, progressIndicator); 
    } 
    finally 
    { 
     //Remove progress list 
     ConcurrentQueue<string> temp; 
     _progressInfo.TryRemove(progressKey, out temp); 
    } 

} 

public List<string> GetSyncProgress(Guid progressKey) 
{ 
    ConcurrentQueue<string> progressOutput; 
    if (!_progressInfo.TryGetValue(progressKey, out progressOutput)) 
    { 
     //the key did not exist, retun null; 
     return null; 
    } 

    //transform the queue to a list and return it. 
    return progressOutput.ToList(); 
} 

private void ReportSyncProgress(string value, Guid progressKey) 
{ 
    ConcurrentQueue<string> progressOutput; 
    if (!_progressInfo.TryGetValue(progressKey, out progressOutput)) 
    { 
     //the key did not exist, progress is being reported for a completed item... odd. 
     return; 
    } 

    //This is the requests specific queue of output. 
    progressOutput.Enqueue(value); 
} 
+0

Danke Scott für all deine Hilfe, ich werde diesen Montag versuchen. – siegs

+0

Scott, ich wollte dir nur noch einmal danken. Hab heute Ihre Lösung genutzt und konnte mit der Architektur weitermachen - Sie sind ein Lebensretter. – siegs

Verwandte Themen