我正在使用WebApi Rest服务的"Post"异步方法:
public async Task<object> Post([FromBody]string data)
{
object response = ExecuteServerLogics(data);
return response;
}
以上代码效果良好,但在一些客户端调用中,我们遇到了性能问题。
阅读了一些文章后,我注意到我们的WebApi Rest服务并没有真正地与其传入的Web请求异步工作, 因为我们忘记使用async/await模式:
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
return ExecuteServerLogics(data);
});
return response;
}
在此修复之后,我们注意到性能有所改善,但我们发现另一个严重的问题: 当访问HttpContext.Current时,它返回空引用:
public async Task<object> Post([FromBody]string data)
{
object response = await Task<object>.Run( () =>
{
var currentContext = HttpContext.Current; // Returns Null!
return ExecuteServerLogics(data);
});
return response;
}
我们试图找到一个解决方法,大多数帖子都建议将工作线程的HttpContext引用传递给执行服务器逻辑的内部任务。这种解决方案的问题在于,服务器逻辑方法使用许多静态类,这些静态类使用"HttpContext.Current",例如:
- 日志记录器调用。
- 检索用户身份的静态安全类。
- 检索传入请求的会话数据等静态安全类。
因此,传递工作线程的"HttpContext.Current"引用无法解决该问题。
当我们尝试下一个解决方案时:
public async Task<object> Post([FromBody]string data)
{
// Save worker context:
var currentContext = HttpContext.Current;
object response = await Task<object>.Run( () =>
{
// Set the context of the current task :
HttpContext.Current = currentContext ; // Causes the calls not to work asynchronously for some reason!
// Executes logics for current request:
return ExecuteServerLogics(data);
});
return response;
}
由于某些原因,我们发现性能再次变差了,就像它又开始同步工作一样。
我们的问题是:
1. 为什么在最后一个示例中,在await任务中设置 "HttpContext.Current" 会导致请求返回与同步结果相似的糟糕性能结果?
2. 是否有另一种方法可以在调用 "ExecuteServerLogics" 的内部任务以及所有调用 "HttpContext.Current" 的静态类中使用 "HttpContext.Current"?我是否在整个设计上都做错了一些事情?
谢谢!
async
和await
时,HttpContext.Current
会适当地流动。如果您明确使用后台线程(例如Task.Run
),则不会流动。 - Stephen Cleary