长时间运行的WCF调用会阻止任何后续请求

时间:2017-08-30 10:03:32

标签: c# wcf sharepoint

我目前正在托管SharePoint WCF Web服务以进行长时间运行。基本上,此操作将发出另一个HTTP请求来检索信息(此另一个调用最多可能需要2分钟)。该服务的代码如下(我删除了一些代码行):

public async Task<Stream> Get()
{
    WebOperationContext operationContext = WebOperationContext.Current;

    using (var client = new HttpClient())
    {
        client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
        client.Timeout = TimeSpan.FromMinutes(5);

        HttpResponseMessage response = await client.GetAsync(url);

        if (response.IsSuccessStatusCode)
        {
            string result = await response.Content.ReadAsStringAsync();

            operationContext.OutgoingResponse.ContentType = "application/json";

            return new MemoryStream(Encoding.UTF8.GetBytes(result));
        }
        else
        {
            WebOperationContext.Current.OutgoingResponse.StatusCode = response.StatusCode;
        }
    }

    return null;
}

我通过AJAX从AngularJS应用程序调用此Web服务,问题是它阻止了所有后续调用,甚至是“正常”调用。例如,当GetAsync方法执行需要90秒时,我甚至无法在浏览器中切换页面,直到该方法完全执行...我试图将ConcurrencyMode放到MultipleReentrant,我尝试不使用同步上下文,我尝试将InstanceContextMode设置为PerCall但它没有改变任何内容,服务器仍然等待处理完成后再处理其他行动......

1 个答案:

答案 0 :(得分:0)

经过大量调查,我终于找到了问题。事实是我在WCF服务中使用会话,在这种情况下,WCF按顺序处理呼叫,这意味着一旦呼叫开始,所有其他呼叫(甚至呼叫切换页面)都必须等待它。在接受治疗之前完成了......

要解决此问题,您必须问问自己,您的服务是否真的需要能够在会话中编写。如果确实如此,据我所知,没有解决它。但是,如果您的服务只需要从会话中读取信息,则可以使用以下方式覆盖global.asax文件:

if (Request.Path.Contains("myservice.svc"))
{
     HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);
}

这确保WCF在只读模式下使用会话,在这种情况下,可以并行处理调用。