C# - Return WCF Rest 服务的进度
C# - Return progress from WCF Rest Service
在我的服务中,我目前有一些任务和一个不断更新列表的 ReportProgress 方法。我如何 return 将该列表添加到我的客户端主机应用程序?
服务端:
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 是一个列表,我需要我的客户在更新时实时接收它。
谢谢!
因为 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);
}
在我的服务中,我目前有一些任务和一个不断更新列表的 ReportProgress 方法。我如何 return 将该列表添加到我的客户端主机应用程序?
服务端:
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 是一个列表,我需要我的客户在更新时实时接收它。
谢谢!
因为 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);
}