在自己的线程上执行的任务

时间:2018-02-11 01:14:36

标签: c# multithreading asp.net-core async-await

我有一个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方法中的调用堆栈,当断点指向结果时,调用堆栈在存储库中启动而不是在控制器中。

1 个答案:

答案 0 :(得分:5)

任务并行库和async / await功能的全部目的是它们抽象出底层的Threads逻辑。除非您正在使用一个项目,该项目使用一个框架,该框架具有在UI线程上运行的同步上下文(即:WinForms,WPF,Xamarin),否则您应该让框架确定是否给定{ {1}}应该在当前线程或其他线程上运行。