EF6两个上下文与单个上下文有两个等待 [英] EF6 two contexts vs. single context with two awaits
问题描述
哪些是更好的表现方法?
注意:对于某些操作,我最多可以执行五个独立查询。
Which of these is a better approach for performance? Note: For some operations I have up to five independent queries to execute.
var foo = await context.foos.ToListAsync();
var bar = await context.bars.ToListAsync();
vs。
var fooTask = context1.foos.ToListAsync();
var barTask = context2.bars.ToListAsync();
await Task.WhenAll(fooTask , barTask);
使用相同的上下文没有等待,这将是非常好的,但这个答案提到这是不可能的。
It would be great to use the same context without awaits, but this answer mentions that is not possible.
推荐答案
出来,DbContext不是线程安全的,因此,并行执行查询的唯一选择是为每个线程/任务创建一个新的DbContext。
As you found out, the DbContext is not thread safe, therefore the only option to really run the queries in parallel would be to create a new DbContext for each Thread/Task.
开销创建一个新的DbContext是相当低的。
https://msdn.microsoft.com/en-us/library /cc853327.aspx
The overhead of creating a new DbContext is pretty low. https://msdn.microsoft.com/en-us/library/cc853327.aspx
由于对象将来自不同的DbContexts,并且进一步提高性能,我建议您还可以使用NoTracking()
Since the object will come from different DbContexts and to further increase performance I recommend you also use NoTracking()
编辑:
我用一个数据库做了一个简单的测试程序:
I made a simple test program with a database I had:
class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Warming up db context...");
using (var db = new TestDbContext())
{
Console.WriteLine(db.AuditLogItems.ToList().Count);
}
// 1st run
RunAsync();
RunTasked();
// 2nd run
RunAsync();
RunTasked();
Console.ReadKey();
}
private static void RunAsync()
{
Task.Run(async () =>
{
var sw = Stopwatch.StartNew();
List<AuditLogItem> list1;
List<AuditLogItem> list2;
using (var db = new TestDbContext())
{
list1 = await db.AuditLogItems.AsNoTracking().ToListAsync();
list2 = await db.AuditLogItems.AsNoTracking().ToListAsync();
}
sw.Stop();
Console.WriteLine("Executed {0} in {1}ms. | {2}", "Async", sw.ElapsedMilliseconds, list1.Count + " " + list2.Count);
}).Wait();
}
private static void RunTasked()
{
Func<List<AuditLogItem>> runQuery = () =>
{
using (var db = new TestDbContext())
{
return db.AuditLogItems.AsNoTracking().ToList();
}
};
var sw = Stopwatch.StartNew();
var task1 = Task.Run(runQuery);
var task2 = Task.Run(runQuery);
Task.WaitAll(task1, task2);
sw.Stop();
Console.WriteLine("Executed {0} in {1}ms. | {2}", "Tasked", sw.ElapsedMilliseconds, task1.Result.Count + " " + task2.Result.Count);
}
}
输出是:
Warming up db context...
5908
Executed Async in 293ms. | 5908 5908
Executed Tasked in 56ms. | 5908 5908
Executed Async in 194ms. | 5908 5908
Executed Tasked in 32ms. | 5908 5908
所以是的,选项2更快...
So yes, option 2 is faster...
这篇关于EF6两个上下文与单个上下文有两个等待的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!