我在.Net 4.0 VS2010环境中有一个在MVC 4中运行的项目。我需要处理一个长时间运行的SQL任务,而不会让用户在前端等待那么长时间。 MVC 4 Web应用程序调用业务层,该业务层调用数据层方法,该方法使用下面的代码片段执行SP。
public DataSet ExecuteSP()
{
dbc = database.GetStoredProcCommand('long_running_sp');
dbc.CommandTimeout = 300;
foreach (SPParams p in spParams)
{
dbc.Parameters.Add(new SqlParameter(p.ParamName, p.ParamValue));
}
DataSet ds = _database.ExecuteDataSet(dbc);
return ds;
}
我尝试的两个选项是使用同步控制器,显然不起作用,然后另一个使用AsyncController。我发现在数据层中调用存储过程后,两个选项都挂起了我的网站。然后我在AsyncController中介绍了Task.Factory.StartNew方法。有效。然后我在同步控制器中应用了相同的功能,它也在那里工作。
现在的问题是:如果我需要申请的是Task.Factory.StartNew,那么为什么还要使用AsyncController呢?或者更好的是为什么不完全抛弃Task.Factory.StartNew并且只需要Service Broker Activation
这里有什么更好的选择?
答案 0 :(得分:2)
AsyncController和普通控制器之间的区别在于您可以同时处理更多请求。
你所拥有的局面是一种“一劳永逸”的局面。 AsyncController更适合您有长请求的情况(通常是网络或I / O绑定)。虽然从客户端角度来看,您不会注意到响应时间的任何差异,但服务器级别存在差异。
如果使用同步控制器,它将阻止该线程。 IIS在线程池中可用的线程数量有限。如果阻止线程,IIS可能会用完线程。结果是其他线程排队,因为你有许多被阻塞的线程。使用异步控制器,您可以释放这些线程,而不会执行任何操作,因此可以为其他请求提供服务。
因此,从单个用户的角度来看,响应时间将是相同的,因为您仍然需要等待响应。从多用户角度来看,总响应时间会更好,因为您可以同时为更多用户提供服务。
如前所述,如果您正在执行即发即弃,则没有理由使用异步控制器,因为您想要的只是触发查询并将结果返回给用户。对于这种情况,您正在应用的方法是正确的。
如果需要将结果返回给用户,最好使用异步控制器,因为这样可以释放等待的线程。 (也就是说,如果它是网络或IO绑定的,因为如果它受CPU约束,则根本没有任何收益)