2016-05-13 3 views
0

В моей службе у меня в настоящее время есть несколько задач и метод ReportProgress, который постоянно обновляет список. Как я могу вернуть этот список в мое клиентское хост-приложение?C# - Возврат из службы обслуживания WCF

служба сторона:

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

... в задаче у меня есть прогресс отчет в цикле:

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

... и вот мой метод отчета:

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

progressOutput - это список, и мне нужен мой клиент, чтобы получать его в реальном времени по мере его обновления.

Спасибо!

+0

Вы сказали нам свои требования, вы никогда не говорили нам о том, какую проблему вы должны выполнить для выполнения этих требований. Вы еще не просмотрели [методы обратного вызова WCF] (https://adamprescott.net/2012/08/15/a-simple-wcf-service-callback-example/)? –

+0

Проблема в том, что я не знаю, как продолжать возвращать прогресс по мере его обновления. Я еще не изучал методы обратного вызова. – siegs

+0

как вы совершаете обратный вызов через службу отдыха? – siegs

ответ

1

Поскольку службы Rest не имеют сеансов, вы не можете сделать обычный метод обратного вызова WCF. Вместо этого вам нужно будет передать какой-то токен, а затем использовать этот токен, чтобы получить информацию о ходе.

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

Спасибо Скотту за вашу помощь, я собираюсь попробовать этот понедельник. – siegs

+0

Скотт, просто хотел поблагодарить тебя снова. Сегодня вы использовали свое решение и смогли двигаться вперед по архитектуре - вы - спасатель. – siegs

Смежные вопросы