我阅读了以下文章:
在Asp.Net Core中什么时候应该使用Task.Run?
在ASP.NET Core控制器中允许使用Task.Run吗?
在docs.microsoft
的第一篇文章中,我们可以看到这个声明:
如果有异步API可用,请异步调用数据访问、I/O和长时间运行的操作API。 不要使用Task.Run将同步API转换为异步形式。
我对这个声明不太理解。我对何时以及何处应该使用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());
}
但对于第二种方法,我可以这样更改:
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");
}
我不知道我的看法是否正确?这些方法是正确的吗?有没有办法运行第一个 API async
?
谢谢。
编辑 1)
感谢 Stephen Cleary。
如果我们假设这个句子: 我们在 Web API 的 Web 方法中使用 async
方法来防止阻塞线程池线程并处理更多请求 ...
请考虑以下代码:
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;
}
}
我能否从我的 Web API 中调用 async
并释放线程池线程呢?
谢谢。