简体   繁体   中英

C# - Return progress from WCF Rest Service

In my service I currently have a few tasks and a ReportProgress method that continually updates a List. How can I return that list to my client host application?

Service side:

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

...within the task I have a progress Report in a loop:

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

...and here is my report method:

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

progressOutput is a List and I need my client to receive that in real time as it is updated.

Thank you!

Because Rest services don't have sessions you can't make normal WCF callback method. Instead what you will need to do is pass in some kind of token and then use that token to get the progress information.

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);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM