我们有一个网站现在正在与并发用户作斗争。
这是该项目的非常高级的背景:
- 旧版 ASP.NET MVC 3 项目 (.NET 4)
- 无法对核心代码进行任何重大重写
- 执行时间最长的主要入口点是控制器
SubmitSearch
上的操作。Search
平均响应时间为 5-10 秒。
因此,正如第二点概述的那样,我们不想在这个项目上花费太多时间重写大段。但是,我们想尝试增加并发用户。我们不打算更改任何其他内容或提高性能,因为这需要更多的工作。
我们看到的是,随着越来越多的人点击SubmitSearch
,网站总体上会变慢。这很可能是由于所有 IIS 线程都被锁定在执行搜索。
我们正在寻求在普通 CLR 线程上实现AsyncController
并执行该操作。SubmitSearch
这是我们想要实现它的方式:
假设这是原始SubmitSearch
方法:
/// <summary>
/// Submits a search for execution.
/// </summary>
/// <param name="searchData">The search data</param>
/// <returns></returns>
public virtual ActionResult SubmitSearch(SearchFormModel searchData)
{
//our search code
}
我们希望转换的最快方法AsyncController
是简单地这样做:
/// <summary>
/// Submits a search for execution.
/// </summary>
/// <param name="searchData">The search data</param>
/// <returns></returns>
protected virtual ActionResult SubmitSearch(SearchFormModel searchData)
{
//our search code
}
/// <summary>
/// Asynchronous Search entry point
/// </summary>
/// <param name="searchData"></param>
public void SubmitSearchAsync(SearchFormModel searchData)
{
AsyncManager.OutstandingOperations.Increment();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
ActionResult result = SubmitSearch(searchData);
AsyncManager.Parameters["result"] = result;
AsyncManager.OutstandingOperations.Decrement();
});
return;
}
/// <summary>
/// Called when the asynchronous search has completed
/// </summary>
/// <param name="result"></param>
/// <returns></returns>
public ActionResult SubmitSearchCompleted(ActionResult result)
{
//Just return the action result
return result;
}
当然这不起作用,因为在整个代码中,我们都在引用HttpContext.Current
,我们知道最终会null
采用这种方法。
所以我们当时希望这样做SubmitSearchAsync
:
/// <summary>
/// Asynchronous Search entry point
/// </summary>
/// <param name="searchData"></param>
public void SubmitSearchAsync(SearchFormModel searchData)
{
AsyncManager.OutstandingOperations.Increment();
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
ActionResult result = null;
AsyncManager.Sync(() =>
{
result = SubmitSearch(searchData);
});
AsyncManager.Parameters["result"] = result;
AsyncManager.OutstandingOperations.Decrement();
});
return;
}
这解决了这个问题。
所以这是我的担忧:在方法中
包装执行是否会破坏使用此模型的目的?换句话说,当我们在方法中时,我们是否回到了 IIS 线程,这让我们回到了原点?SubmitSearch
AsyncManager.Sync
AsyncManager.Sync
谢谢