我有這段代碼(同步方法):
// ...
var processingTasks = Enumerable.Range(0, count)
.Select(x => Task.Run(async () =>
await CallApiAndUpdateSthAsync(accounts[x], cancellationToken)))
.ToList();
var processingTasksAggregate = Task.WhenAll(processingTasks);
Task.WaitAny(globalStatusMonitoringTask, processingTasksAggregate);
我對這部分特別感興趣:
Task.Run(async () => await CallApiAndUpdateSthAsync(accounts[x], cancellationToken))
如果我洗掉Task.Run? 即改成:
CallApiAndUpdateSthAsync(accounts[x], cancellationToken)
我想洗掉它,因為在執行緒池中排隊任務(通過Task.Run)似乎是多余的,但我的同事建議我不要這樣做,因為可能出現死鎖
整個方法作為后臺作業運行,類似于 Hangfire:

[編輯 1]:它是一個 .NET Framework(不是 Core)應用程式。
uj5u.com熱心網友回復:
如果我洗掉了Task.Run,??它會有所不同(從可能的死鎖角度來看)嗎?
可能。常見的死鎖有兩個部分(鏈接到我的博客):
- 阻塞異步代碼。您的代碼正在使用
Task.WaitAny. - 一次只允許一個執行緒的背景關系。
由于您的代碼顯然具有 (1),因此您可以得出結論,如果它具有 (2),它將死鎖。可能導致死鎖的常見背景關系包括 ASP.NET pre-Core 和 GUI 執行緒背景關系。如果您的應用程式沒有一次一個執行緒的背景關系,那么就不會出現死鎖。
我想洗掉它,因為在執行緒池中排隊任務(通過 Task.Run)似乎是多余的
并不真地。“異步”并不意味著“在不同的執行緒上運行”,因此兩者并不多余。問題是洗掉是否Task.Run會起作用。它可能會,也可能不會。如果此代碼在單執行緒背景關系中運行,則洗掉Task.Run將導致死鎖。如果CallApiAndUpdateSthAsync可以同步運行(即,由于快取命中),那么洗掉Task.Run將導致呼叫串行而不是并行運行,這也可能是不可取的。
uj5u.com熱心網友回復:
如果它是一個asp.net core應用程式(不僅僅是老學校asp.net),那么任務死鎖就沒有問題。SynchronizationContext(沒有 可能導致死鎖ConfigureAwait(false))在asp.net core. ASP.NET Core 中沒有 SynchronizationContext。
也沒有Task.Run-CallApiAndUpdateSthAsync將在您當前的執行緒上執行,直到第一個await里面。with Task.Run- wholeCallApiAndUpdateSthAsync將在您的主執行之外執行。Task.Yield您可以通過在開頭添加來修復它CallApiAndUpdateSthAsync。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/410853.html
標籤:
