C#-从WCF Rest服务返回进度

C#-从WCF Rest服务返回进度,c#,wcf,rest,progress,C#,Wcf,Rest,Progress,在我的服务中,我目前有一些任务和一个ReportProgress方法,可以不断更新列表。如何将该列表返回到客户端主机应用程序 服务方: public async void BeginSync(string dbId) { var progressIndicator = new Progress<string>(ReportSyncProgress); var output = await BeginSyncTaskAsync(dbId, progressIndicat

在我的服务中,我目前有一些任务和一个ReportProgress方法,可以不断更新列表。如何将该列表返回到客户端主机应用程序

服务方:

public async void BeginSync(string dbId)
{
    var progressIndicator = new Progress<string>(ReportSyncProgress);
    var output = await BeginSyncTaskAsync(dbId, progressIndicator);                             
}
…以下是我的报告方法:

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);
}
私有静态ConcurrentDictionary\u progressInfo;
//您永远不应该执行“async void”,WCF可以使用任务和异步后缀来处理。
//看https://blogs.msdn.microsoft.com/endpoint/2010/11/12/simplified-asynchronous-programming-model-in-wcf-with-asyncawait/
公共异步任务BeginSyncAsync(字符串dbId,Guid progressKey)
{
if(!\u progressInfo.TryAdd(progressKey,new ConcurrentQueue()))
{
抛出新的InvalidOperationException(“正在使用进度键”);
}
var progressIndicator=新进度((值)=>ReportSyncProgress(值,progressKey));
尝试
{
var输出=等待BeginSyncTaskAsync(dbId,progressIndicator);
}
最后
{
//删除进度列表
并发队列温度;
_progressInfo.TryRemove(progressKey,out temp);
}
}
公共列表GetSyncProgress(Guid progressKey)
{
并行队列输出;
if(!\u progressInfo.TryGetValue(progressKey,out progressOutput))
{
//密钥不存在,请重新运行null;
返回null;
}
//将队列转换为列表并返回它。
返回progressOutput.ToList();
}
私有void ReportSyncProgress(字符串值,Guid progressKey)
{
并行队列输出;
if(!\u progressInfo.TryGetValue(progressKey,out progressOutput))
{
//密钥不存在,正在报告已完成项的进度…奇数。
返回;
}
//这是特定于请求的输出队列。
progressOutput.Enqueue(值);
}

因为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);
}
私有静态ConcurrentDictionary\u progressInfo;
//您永远不应该执行“async void”,WCF可以使用任务和异步后缀来处理。
//看https://blogs.msdn.microsoft.com/endpoint/2010/11/12/simplified-asynchronous-programming-model-in-wcf-with-asyncawait/
公共异步任务BeginSyncAsync(字符串dbId,Guid progressKey)
{
if(!\u progressInfo.TryAdd(progressKey,new ConcurrentQueue()))
{
抛出新的InvalidOperationException(“正在使用进度键”);
}
var progressIndicator=新进度((值)=>ReportSyncProgress(值,progressKey));
尝试
{
var输出=等待BeginSyncTaskAsync(dbId,progressIndicator);
}
最后
{
//删除进度列表
并发队列温度;
_progressInfo.TryRemove(progressKey,out temp);
}
}
公共列表GetSyncProgress(Guid progressKey)
{
并行队列输出;
if(!\u progressInfo.TryGetValue(progressKey,out progressOutput))
{
//密钥不存在,请重新运行null;
返回null;
}
//将队列转换为列表并返回它。
返回progressOutput.ToList();
}
私有void ReportSyncProgress(字符串值,Guid progressKey)
{
并行队列输出;
if(!\u progressInfo.TryGetValue(progressKey,out progressOutput))
{
//密钥不存在,正在报告已完成项的进度…奇数。
返回;
}
//这是特定于请求的输出队列。
progressOutput.Enqueue(值);
}

您告诉我们您的需求,但从未告诉我们您在满足这些需求时遇到了什么问题。你看了吗?问题是我不知道如何继续返回更新的进度。我还没有研究回调方法。如何通过rest服务进行回调?哦,我没有注意到这是一个rest服务。Rest服务不能有回调。使用rest服务进行此操作的唯一方法是让客户端使用某种请求id轮询某个端点以检查进程是否存在异步设置列表值的方法,然后我可以在该进程完成之前调用该列表上的Get函数?您告诉我们您的要求,您从未告诉我们您在满足这些要求时遇到了什么问题。你看了吗?问题是我不知道如何继续返回更新的进度。我还没有研究回调方法。如何通过rest服务进行回调?哦,我没有注意到这是一个rest服务。Rest服务不能有回调。使用rest服务进行此操作的唯一方法是让客户端使用某种请求id轮询某个端点,以检查进程是否存在异步设置列表值的方法,然后我可以调用该列表上的Get函数,直到进程完成?感谢Scott的帮助,我将在本周一尝试。Scott,我只是想再次感谢你。今天使用了您的解决方案,并且能够继续推进体系结构-您是一个救星。感谢Scott的所有帮助,我将在本周一尝试。Scott,只想再次感谢您。今天使用了您的解决方案,并且能够继续推进体系结构—您是一个救生员。