【发布时间】:2013-10-20 01:22:44
【问题描述】:
我们现在有一个网站正在与并发用户作斗争。
这是项目的非常高级的背景:
- 旧版 ASP.NET MVC 3 项目 (.NET 4)
- 无法对核心代码进行任何重大重写
- 执行时间最长的主入口点是
Search控制器上的SubmitSearch操作。平均响应时间为 5-10 秒。
因此,正如第二点所述,我们不想在这个项目上花费太多时间重写大段。但是,我们想尝试增加并发用户。我们不打算更改任何其他内容或提高性能,因为这需要更多的工作。
我们看到的是,随着更多人点击SubmitSearch,网站的速度总体上会变慢。这很可能是由于所有 IIS 线程都被锁定在执行搜索。
我们正在寻求实现AsyncController 并使SubmitSearch 操作在普通CLR 线程上执行。以下是我们想要实现它的方式:
假设这是原始的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;
}
这解决了问题。
所以这是我的担忧:
在AsyncManager.Sync 方法中包装SubmitSearch 的执行是否会破坏使用此模型的目的?换句话说,当我们在 AsyncManager.Sync 方法中时,我们是否回到了 IIS 线程,这让我们回到了第一阶段?
谢谢
【问题讨论】:
标签: asp.net-mvc multithreading asynccontroller