Ari*_*ian 6 c# asp.net multithreading task asp.net-core
我读过这些文章:
\n\n我什么时候应该在 Asp.Net Core 中使用 Task.Run?
\n是否允许在 ASP.NET Core 控制器中使用 Task.Run?
\n在第一篇文章中docs.microsoft我们可以看到这样的说法:
\n\n如果异步 API 可用,则异步调用数据访问、I/O 和长时间运行的操作 API。请勿使用 Task.Run 使\n同步 API 变为异步。
\n
我不太理解这个说法。我对应该在何时何地使用Task.Run以及何时何地应该(可以)编写异步 Web API 感到困惑。例如,考虑这个方法:
public int DoSomeHeavyWork()\n{\n // Consider heavy computations\n int i = 10;\n i = i * 2;\n i = i + 4;\n return i;\n}\nRun Code Online (Sandbox Code Playgroud)\n这个方法:
\npublic void SaveSomthingInDb(Order ord)\n{\n _dbContext.Orders.Add(ord);\n _dbContext.SaveChange();\n}\nRun Code Online (Sandbox Code Playgroud)\n根据上面的说法,我应该同步编写一个Web方法,因为没有async版本:
public IActionResult API_DoSomeHeavyWork()\n{\n return Ok(DoSomeHeavyWork());\n}\nRun Code Online (Sandbox Code Playgroud)\n但对于方法2我可以这样改变:
\npublic async Task SaveSomthingInDbAsync(Order ord)\n{\n _dbContext.Orders.Add(ord);\n await _dbContext.SaveChangeAsync();\n}\nRun Code Online (Sandbox Code Playgroud)\n所以我可以为此编写一个 API,如下所示:
\npublic async Task<IActionResult> API_SaveSomthingInDbAsync(Order ord)\n{\n await SaveSomthingInDbAsync(ord);\n return Ok("Object Added");\n}\nRun Code Online (Sandbox Code Playgroud)\n不知道\xd9\x87s我对这个问题的看法是否正确?写这些方法是真的吗?有什么办法可以运行第一个 APIasync吗?
谢谢
\n编辑1)
\n感谢“斯蒂芬·克利里”。
\n如果我们假设这句话:我们在Web API的Web方法中使用async方法来防止阻塞线程池线程并接受更多请求......
请考虑这段代码:
\nawait _context.Order.ToListAsync();\nRun Code Online (Sandbox Code Playgroud)\n根据此代码,有一个名为的程序集Microsoft.EntityFrameworkCore,它有一个async名为的方法ToListAsync:
public static Task<List<TSource>> ToListAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))\nRun Code Online (Sandbox Code Playgroud)\n第一个问题是如何ToListAsync实施?是这样实现的吗?
public static Task<List<TSource>> ToListAsync<TSource>(...)\n{\n Task.Run(()=>{ <Some thing>.ToList() });\n}\nRun Code Online (Sandbox Code Playgroud)\n第二个问题是该方法是否DoSomeHeavyWork放置在单独的程序集中并以这种方式重写:
public Task<int> DoSomeHeavyWork()\n{\n Task.Run(() => \n {\n // Consider heavy computations\n int i = 10;\n i = i * 2;\n i = i + 4;\n return i;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\nasync然后我可以从我的 Web API 和空闲线程池线程调用它吗?
谢谢
\n我对应该在何时何地使用 Task.Run 感到困惑
在 ASP.NET 上,几乎从来没有。您可以采用“从不”作为一般规则。
以及我应该(可以)编写异步 Web API 的地点和时间。
当且仅当它们调用异步代码时,您的控制器操作才应该是异步的。一般来说,对于执行 I/O 的所有代码,您应该更喜欢最低级别的异步 API。然后,仅当您的操作方法需要调用该异步代码时,它们才是异步的。
我应该同步编写一个Web方法,因为没有异步版本...但是对于方法2我可以这样改变它
是的。
有什么方法可以运行第一个 API 异步吗?
可以这样想:如果有同步(CPU 密集型)工作要做,那么该工作需要一个线程。它已经在线程池线程上运行(因为 Web 请求在线程池中的线程上运行)。Task.Run会将该工作移至不同的线程池线程,但它仍将在线程池线程上运行。所以Task.Run没有任何帮助;它只会增加开销并且没有任何好处。因此,一般规则是“不要Task.Run在 ASP.NET 上使用”。