我对C#中的异步行为的了解有点生疏,我想知道是否通过异步更改某些代码对我们有利,或者它是否实际上会降低代码的效率。
我有一组方法,每个方法都通过实体框架执行存储过程。我们返回IEnumerable<SomeDataType>
。
此集合中的每个方法都可以独立于其他方法运行,因此我开始考虑并行运行它们。
一位前同事告诉我有关数据库查询全部同步运行的事情,并且在任务中包装数据库调用代码会降低系统速度,这一点突然出现在我脑海中。
我们的方法如下:
private IEnumerable<Models.Permission> PermissionsForUser(Context entities,int userId)
{
var userperms = entities.sssp_GetUserPermissions(userId);
return ...
}
答案 0 :(得分:2)
在任务中包装DB调用代码会有好处吗?
这取决于。如果用Task
来表示&#34;使用数据提供者公开的自然异步API,例如ADO.NET或Entity Framework公开的XXXAsync,那么可能受益如果您有并发请求命中数据库,并且您希望释放您的线程同时处理其他请求。它肯定不会加速您的查询。
我是否会通过在任务中包装数据库调用来减慢我们的系统速度?
再次,这取决于。同样的事情适用于你的第一个问题以及你的意思&#34;任务&#34;。你必须记住Task != Thread
。如果您想通过调用Task.Run
来包装数据库查询,那么您将有效地使用"async over sync"反模式。它可能最终也会减慢您的查询速度,您必须确定基准以确定。
DB查询是否都以同步方式执行?
数据库查询可以同步或异步执行,具体取决于提供程序公开的API。进行数据库调用自然是异步的,这意味着不需要为这些查询使用任何额外的线程来释放正在使用的线程。如果您有多个可以同时执行的查询,那么使用这些asynchorouns API可以从中受益。
答案 1 :(得分:0)
任务并行库不会减慢代码速度,库会引入.net以利用当今存在的多核处理器。
因此,如果您向数据库发出两个查询并不相互依赖,那么您可以创建两个任务并调用将并行执行代码的数据库。
默认运行任务使用线程池如果你创建长时间运行的任务减慢了事情,因为调用数据库可能是长时间运行的任务我建议你使用TaskCreationOptions.LongRunning
进行长时间运行的任务示例代码如:
Task[] tasks = new Task[2];
task[0] = Task.Factory.StartNew(calltodatabase1
, TaskCreationOptions.LongRunning
, cancellationTokenSource.Token);
task[1] = Task.Factory.StartNew(calltodatabase2
, TaskCreationOptions.LongRunning
, cancellationTokenSource.Token);
Task.WaitAll(tasks);