Entity Framework SaveChanges() vs. SaveChangesAsync() and Find() vs. FindAsync()
我一直在寻找上面两对之间的差异,但是没有找到任何清楚地解释它以及何时使用一个或另一个的文章。
那么
在
在服务器端,当我们使用
它仅有助于防止UI在客户端浏览器上阻塞吗? 还是它们之间有什么优缺点?
任何时候需要在远程服务器上执行操作时,程序都会生成请求,将其发送,然后等待响应。我将使用
假设您有一个列表
1 2 3 4 5 |
首先,创建一个
要解决此问题,您可以执行以下两项操作之一。首先是您可以启动新线程来处理插入。尽管这将释放调用线程以继续执行,但您创建了一个新线程,该线程将坐在那里等待。不需要这些开销,这就是
对于I / O操作,
1 2 3 4 5 6 7 | using(var context = new MyEDM()) { Console.WriteLine("Save Starting"); context.MyTable.AddRange(myList); await context.SaveChangesAsync(); Console.WriteLine("Save Complete"); } |
这是很小的变化,但是对代码的效率和性能产生了深远的影响。那会怎样呢?代码的开头是相同的,创建
1 2 3 4 5 6 7 8 9 10 11 12 | public async Task MyCallingFunction() { Console.WriteLine("Function Starting"); Task saveTask = SaveRecords(GenerateNewRecords()); for(int i = 0; i < 1000; i++){ Console.WriteLine("Continuing to execute!"); } await saveTask; Console.Log("Function Complete"); } |
我不知道为什么会有这样的功能,但是输出的内容显示了
执行进入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | Function Starting Save Starting Continuing to execute! Continuing to execute! Continuing to execute! Continuing to execute! Continuing to execute! .... Continuing to execute! Save Complete! Continuing to execute! Continuing to execute! Continuing to execute! .... Continuing to execute! Function Complete! |
或许:
1 2 3 4 5 6 7 8 9 10 11 | Function Starting Save Starting Continuing to execute! Continuing to execute! Save Complete! Continuing to execute! Continuing to execute! Continuing to execute! .... Continuing to execute! Function Complete! |
这就是
1 2 3 4 5 6 7 8 9 10 | public async Task MyCallingFunction() { List<Task> myTasks = new List<Task>(); myTasks.Add(SaveRecords(GenerateNewRecords())); myTasks.Add(SaveRecords2(GenerateNewRecords2())); myTasks.Add(SaveRecords3(GenerateNewRecords3())); myTasks.Add(SaveRecords4(GenerateNewRecords4())); await Task.WhenAll(myTasks.ToArray()); } |
在这里,您同时具有四个不同的保存记录功能。使用
我尚未触及的一件事是
长话短说,如果您可以选择使用
我剩下的解释将基于以下代码片段。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | using System; using System.Threading; using System.Threading.Tasks; using static System.Console; public static class Program { const int N = 20; static readonly object obj = new object(); static int counter; public static void Job(ConsoleColor color, int multiplier = 1) { for (long i = 0; i < N * multiplier; i++) { lock (obj) { counter++; ForegroundColor = color; Write($"{Thread.CurrentThread.ManagedThreadId}"); if (counter % N == 0) WriteLine(); ResetColor(); } Thread.Sleep(N); } } static async Task JobAsync() { // intentionally removed } public static async Task Main() { // intentionally removed } } |
情况1
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static async Task JobAsync() { Task t = Task.Run(() => Job(ConsoleColor.Red, 1)); Job(ConsoleColor.Green, 2); await t; Job(ConsoleColor.Blue, 1); } public static async Task Main() { Task t = JobAsync(); Job(ConsoleColor.White, 1); await t; } |
注释:当
绿色的旋转完成后,
情况二
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static async Task JobAsync() { Task t = Task.Run(() => Job(ConsoleColor.Red, 2)); Job(ConsoleColor.Green, 1); await t; Job(ConsoleColor.Blue, 1); } public static async Task Main() { Task t = JobAsync(); Job(ConsoleColor.White, 1); await t; } |
备注:这种情况与第一种情况相反。
绿色完成旋转后,
情况3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | static async Task JobAsync() { Task t = Task.Run(() => Job(ConsoleColor.Red, 1)); await t; Job(ConsoleColor.Green, 1); Job(ConsoleColor.Blue, 1); } public static async Task Main() { Task t = JobAsync(); Job(ConsoleColor.White, 1); await t; } |
备注:这种情况将解决以前情况下有关异步方法中的同步部分的问题。立即等待任务
如果要添加其他案例,请随时进行编辑。
此语句不正确:
On server side, when we use Async methods, we also need to add await.
您不需要添加" await",
但从根本上讲,异步调用远不止于此。 这里的想法是,如果在"保存"操作正在进行时还可以(在服务器上)执行其他工作,则应使用