在 ASP.Net 核心中使用 Task.Run
Using Task.Run in ASP.Net Core
我读过这些文章:
ASP.NET Core Performance Best Practices
在docs.microsoft
的第一篇文章中我们可以看到这样的说法:
Call data access, I/O, and long-running operations APIs asynchronously
if an asynchronous API is available. Do not use Task.Run to make a
synchronous API asynchronous.
我不是很理解这个说法。我对何时何地应该使用 Task.Run
以及何时何地应该(可以)编写异步 Web API 感到困惑。例如,考虑这个方法:
public int DoSomeHeavyWork()
{
// Consider heavy computations
int i = 10;
i = i * 2;
i = i + 4;
return i;
}
和这个方法:
public void SaveSomthingInDb(Order ord)
{
_dbContext.Orders.Add(ord);
_dbContext.SaveChange();
}
按照上面的说法,我应该同步写一个web方法,因为没有async
版本:
public IActionResult API_DoSomeHeavyWork()
{
return Ok(DoSomeHeavyWork());
}
但对于方法 2,我可以这样更改:
public async Task SaveSomthingInDbAsync(Order ord)
{
_dbContext.Orders.Add(ord);
await _dbContext.SaveChangeAsync();
}
所以我可以这样写 API:
public async Task<IActionResult> API_SaveSomthingInDbAsync(Order ord)
{
await SaveSomthingInDbAsync(ord);
return Ok("Object Added");
}
我不知道我对这个问题的看法是否正确?写这些方法是真的吗?有什么办法运行第一个APIasync
?
谢谢
编辑 1)
感谢“Stephen Cleary”。
如果我们假设这句话:我们在Web的web方法中使用async
方法API来防止阻塞线程池线程并接受更多的请求...
请考虑此代码:
await _context.Order.ToListAsync();
根据这段代码,有一个名为 Microsoft.EntityFrameworkCore
的程序集,它有一个名为 ToListAsync
:
的 async
方法
public static Task<List<TSource>> ToListAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
第一个问题是ToListAsync
是如何实现的?是这样实现的吗?
public static Task<List<TSource>> ToListAsync<TSource>(...)
{
Task.Run(()=>{ <Some thing>.ToList() });
}
第二个问题是方法 DoSomeHeavyWork
是否放在单独的程序集中并重写为:
public Task<int> DoSomeHeavyWork()
{
Task.Run(() =>
{
// Consider heavy computations
int i = 10;
i = i * 2;
i = i + 4;
return i;
}
}
然后我可以从我的网站 API 和空闲线程池线程中调用它 async
吗?
谢谢
I'm confused about where and when I should use Task.Run
在 ASP.NET 上,几乎从不。您可以采用“从不”作为一般规则。
and where and when I should (can) write async web API.
当且仅当它们调用异步代码时,您的控制器操作才应该是异步的。一般来说,对于执行 I/O 的所有代码,您应该更喜欢最低级别的异步 API。然后你的操作方法只有在需要调用异步代码时才是异步的。
I should write a web method synchronously because there is no async version ... but for method 2 I can change it this way
是的。
Is there any way to run the first API async?
想一想 this way:如果有同步 (CPU-bound) 工作要做,那么该工作需要一个线程。它已经在线程池线程上 运行ning(因为网络请求 运行 来自线程的线程
水池)。 Task.Run
会将工作转移到不同的线程池线程,但它仍会 运行 在线程池线程上。所以 Task.Run
没有任何帮助;它只会增加开销而不会带来任何好处。因此一般规则“不要在 ASP.NET 上使用 Task.Run
”。
我读过这些文章:
ASP.NET Core Performance Best Practices
在docs.microsoft
的第一篇文章中我们可以看到这样的说法:
Call data access, I/O, and long-running operations APIs asynchronously if an asynchronous API is available. Do not use Task.Run to make a synchronous API asynchronous.
我不是很理解这个说法。我对何时何地应该使用 Task.Run
以及何时何地应该(可以)编写异步 Web API 感到困惑。例如,考虑这个方法:
public int DoSomeHeavyWork()
{
// Consider heavy computations
int i = 10;
i = i * 2;
i = i + 4;
return i;
}
和这个方法:
public void SaveSomthingInDb(Order ord)
{
_dbContext.Orders.Add(ord);
_dbContext.SaveChange();
}
按照上面的说法,我应该同步写一个web方法,因为没有async
版本:
public IActionResult API_DoSomeHeavyWork()
{
return Ok(DoSomeHeavyWork());
}
但对于方法 2,我可以这样更改:
public async Task SaveSomthingInDbAsync(Order ord)
{
_dbContext.Orders.Add(ord);
await _dbContext.SaveChangeAsync();
}
所以我可以这样写 API:
public async Task<IActionResult> API_SaveSomthingInDbAsync(Order ord)
{
await SaveSomthingInDbAsync(ord);
return Ok("Object Added");
}
我不知道我对这个问题的看法是否正确?写这些方法是真的吗?有什么办法运行第一个APIasync
?
谢谢
编辑 1)
感谢“Stephen Cleary”。
如果我们假设这句话:我们在Web的web方法中使用async
方法API来防止阻塞线程池线程并接受更多的请求...
请考虑此代码:
await _context.Order.ToListAsync();
根据这段代码,有一个名为 Microsoft.EntityFrameworkCore
的程序集,它有一个名为 ToListAsync
:
async
方法
public static Task<List<TSource>> ToListAsync<TSource>(this IQueryable<TSource> source, CancellationToken cancellationToken = default(CancellationToken))
第一个问题是ToListAsync
是如何实现的?是这样实现的吗?
public static Task<List<TSource>> ToListAsync<TSource>(...)
{
Task.Run(()=>{ <Some thing>.ToList() });
}
第二个问题是方法 DoSomeHeavyWork
是否放在单独的程序集中并重写为:
public Task<int> DoSomeHeavyWork()
{
Task.Run(() =>
{
// Consider heavy computations
int i = 10;
i = i * 2;
i = i + 4;
return i;
}
}
然后我可以从我的网站 API 和空闲线程池线程中调用它 async
吗?
谢谢
I'm confused about where and when I should use Task.Run
在 ASP.NET 上,几乎从不。您可以采用“从不”作为一般规则。
and where and when I should (can) write async web API.
当且仅当它们调用异步代码时,您的控制器操作才应该是异步的。一般来说,对于执行 I/O 的所有代码,您应该更喜欢最低级别的异步 API。然后你的操作方法只有在需要调用异步代码时才是异步的。
I should write a web method synchronously because there is no async version ... but for method 2 I can change it this way
是的。
Is there any way to run the first API async?
想一想 this way:如果有同步 (CPU-bound) 工作要做,那么该工作需要一个线程。它已经在线程池线程上 运行ning(因为网络请求 运行 来自线程的线程
水池)。 Task.Run
会将工作转移到不同的线程池线程,但它仍会 运行 在线程池线程上。所以 Task.Run
没有任何帮助;它只会增加开销而不会带来任何好处。因此一般规则“不要在 ASP.NET 上使用 Task.Run
”。