2 回答

TA貢獻(xiàn)1848條經(jīng)驗(yàn) 獲得超6個(gè)贊
正如指出的這個(gè)頁面(部分更加深入地了解任務(wù)和任務(wù)<T>的CPU綁定的操作),任務(wù)從他們被稱為線程上運(yùn)行,而CPU限制的工作其實(shí)應(yīng)該被包裹在一個(gè)Task.Run如此它”將在另一個(gè)(后臺(tái))線程上運(yùn)行。所以,是的,在異步方法中使用 Task.Run 來進(jìn)行 CPU 綁定或其他阻塞工作是正常且正常的。從頁面引用:
public async Task<int> CalculateResult(InputData data)
{
// This queues up the work on the threadpool.
var expensiveResultTask = Task.Run(() => DoExpensiveCalculation(data));
// Note that at this point, you can do some other work concurrently,
// as CalculateResult() is still executing!
// Execution of CalculateResult is yielded here!
var result = await expensiveResultTask;
return result;
}
CalculateResult() 在調(diào)用它的線程上執(zhí)行。當(dāng)它調(diào)用 Task.Run 時(shí),它會(huì)將昂貴的 CPU 綁定操作 DoExpensiveCalculation() 排入線程池并接收一個(gè)任務(wù)句柄。DoExpensiveCalculation() 最終在下一個(gè)可用線程上并發(fā)運(yùn)行,可能在另一個(gè) CPU 內(nèi)核上。當(dāng) DoExpensiveCalculation() 忙于另一個(gè)線程時(shí),可以進(jìn)行并發(fā)工作,因?yàn)檎{(diào)用 CalculateResult() 的線程仍在執(zhí)行。
一旦遇到 await,CalculateResult() 的執(zhí)行就交給它的調(diào)用者,允許在 DoExpensiveCalculation() 生成結(jié)果時(shí)使用當(dāng)前線程完成其他工作。完成后,結(jié)果將排隊(duì)等待在主線程上運(yùn)行。最終,主線程將返回執(zhí)行CalculateResult(),此時(shí)它將得到DoExpensiveCalculation() 的結(jié)果。

TA貢獻(xiàn)1877條經(jīng)驗(yàn) 獲得超1個(gè)贊
答案是:視情況而定。
您指出了調(diào)度程序,這正是問題所在。如果您在線程池(默認(rèn)調(diào)度程序)上運(yùn)行,那么運(yùn)行同步的 CPU 密集型工作非常好。如果你在 UI 線程上運(yùn)行,這可能會(huì)導(dǎo)致糟糕的用戶體驗(yàn)。
也就是說,雖然這是一個(gè)問題,但這不是你的問題。您的合同已實(shí)施DoSomeStuff
,您將在當(dāng)前調(diào)度程序上運(yùn)行一些工作。由調(diào)用者決定這是否可能是一個(gè)問題,在這種情況下添加一個(gè)Task.Run
以抵消對(duì)另一個(gè)調(diào)度程序的調(diào)用。
簡而言之,不要使用await Task.Run(() => DoCpuBoundWork());
. 讓知道執(zhí)行上下文的調(diào)用者為您決定。
- 2 回答
- 0 關(guān)注
- 200 瀏覽
添加回答
舉報(bào)