我目前正在托管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
放到Multiple
或Reentrant
,我尝试不使用同步上下文,我尝试将InstanceContextMode
设置为PerCall
但它没有改变任何内容,服务器仍然等待处理完成后再处理其他行动......
答案 0 :(得分:0)
经过大量调查,我终于找到了问题。事实是我在WCF服务中使用会话,在这种情况下,WCF按顺序处理呼叫,这意味着一旦呼叫开始,所有其他呼叫(甚至呼叫切换页面)都必须等待它。在接受治疗之前完成了......
要解决此问题,您必须问问自己,您的服务是否真的需要能够在会话中编写。如果确实如此,据我所知,没有解决它。但是,如果您的服务只需要从会话中读取信息,则可以使用以下方式覆盖global.asax文件:
if (Request.Path.Contains("myservice.svc"))
{
HttpContext.Current.SetSessionStateBehavior(SessionStateBehavior.ReadOnly);
}
这确保WCF在只读模式下使用会话,在这种情况下,可以并行处理调用。