我有一个Action,可以访问三个Cosmos DB存储库来检索信息。该操作具有以下代码:
var task1 = _itemRepository.RetrieveByIdAsync(id);
var task2 = _partsRepository.RetrieveForItemAsync(id);
var task3 = _purchasesRepository.RetrieveForItemAsync(id, currentUserId);
var userPurchased = await _userPurchaseRepository.HasUserPurchased(Session.UserId) // this is awaited because it is a SQL task and can only execute one at a time
await Task.WhenAll(task1, task2, task3);
我在调试时注意到任务似乎在不同的线程上运行。 System.Threading.Thread.CurrentThread.ManagedThreadId
与任务运行之前,每个任务以及等待任务之后不同。
进入前的线程ID - 5
项目存储库线程ID - 61
零件存储库线程ID - 5
购买存储库线程ID - 60
WaitAll - 6之后的线程ID
存储库方法最终都会调用一个常见的QueryAsync方法,如下所示:
public async Task<IEnumerable<TDomainObject>> QueryAsync(Expression<Func<TDomainObject, bool>> predicate, FeedOptions options)
{
var query = Client.CreateDocumentQuery<TDomainObject>(Collection.DocumentsLink, options).Where(predicate).AsDocumentQuery();
List<TDomainObject> results = new List<TDomainObject>();
while (query.HasMoreResults)
{
results.AddRange(await query.ExecuteNextAsync<TDomainObject>());
}
return results;
}
我的理解是同一个请求线程应该用于async / await的所有处理,并且我担心我的代码可能没有那么高的性能。
我没有使用线程ID,我只是想确保我没有创建不必要的线程。
编辑:最初让我看到的是我发现QueryAsync
方法中的调用堆栈,当断点指向结果时,调用堆栈在存储库中启动而不是在控制器中。
答案 0 :(得分:5)
任务并行库和async / await功能的全部目的是它们抽象出底层的Threads逻辑。除非您正在使用一个项目,该项目使用一个框架,该框架具有在UI线程上运行的同步上下文(即:WinForms,WPF,Xamarin),否则您应该让框架确定是否给定{ {1}}应该在当前线程或其他线程上运行。