具有Task.Factory.StartNew的同步控制器与MVC 4中的异步控制器与Service Broker激活

时间:2013-05-16 07:49:25

标签: .net sql-server asp.net-mvc asynchronous

我在.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

这里有什么更好的选择?

1 个答案:

答案 0 :(得分:2)

AsyncController和普通控制器之间的区别在于您可以同时处理更多请求。

你所拥有的局面是一种“一劳永逸”的局面。 AsyncController更适合您有长请求的情况(通常是网络或I / O绑定)。虽然从客户端角度来看,您不会注意到响应时间的任何差异,但服务器级别存在差异。

如果使用同步控制器,它将阻止该线程。 IIS在线程池中可用的线程数量有限。如果阻止线程,IIS可能会用完线程。结果是其他线程排队,因为你有许多被阻塞的线程。使用异步控制器,您可以释放这些线程,而不会执行任何操作,因此可以为其他请求提供服务。

因此,从单个用户的角度来看,响应时间将是相同的,因为您仍然需要等待响应。从多用户角度来看,总响应时间会更好,因为您可以同时为更多用户提供服务。

如前所述,如果您正在执行即发即弃,则没有理由使用异步控制器,因为您想要的只是触发查询并将结果返回给用户。对于这种情况,您正在应用的方法是正确的。

如果需要将结果返回给用户,最好使用异步控制器,因为这样可以释放等待的线程。 (也就是说,如果它是网络或IO绑定的,因为如果它受CPU约束,则根本没有任何收益)