3

我有一個.NET 4.5.1 WCF服務,它處理來自將由成千上萬的用戶使用的應用程序的同步。我目前使用Task.WaitAll,如下所示,它工作正常,但我讀到,這是不好的,可能會導致死鎖等我相信我試過WhenAll在過去,它沒有工作,我不記得作爲問題爲了確保我正確地做到這一點,我再次回到此處進行審查。我關心的是在這種使用中是否需要和優先使用阻塞,因此,WCF服務方法爲什麼WaitAll似乎沒有問題。在WCF方法中使用Task.WaitAll

我有大約十幾個方法,每個方法都會更新實體框架6中的一個實體,使用現有數據處理傳入數據並進行必要的更改。這些方法中的每一個都可能很昂貴,所以我想要使用並行性來主要使這個強大的24核心服務器上的所有方法同時工作。每個方法都以Task的形式返回,並將其內容包裝在Task.Run中。 DoSync方法創建了一個新的List,並將這些同步方法中的每一個添加到列表中。然後我調用Task.WaitAll(taskList.ToArray()),所有的工作都很好。

這是否正確嗎?我想確保此方法可以很好地擴展,不會導致問題,並且可以在WCF服務場景中正常工作。

+0

我知道這個問題是舊的,但幾乎沒有理由在WCF服務中使用異步。對於並行性,您可以在其他情況下使用'Parallel.For/Foreach'或PLINQ'.AsParallel()'。 –

回答

5

在高規模服務中,使用異步IO(您不是 - 您使用的是Task.Run)通常是一個好主意。 「高標度」的定義非常鬆散。異步IO在服務器上的好處是它不會阻塞線程。這導致更少的內存使用和更少的上下文切換。這就是它的全部。

如果你不需要這些好處,你可以使用同步IO和阻塞所有你喜歡的東西。什麼壞事都會發生。瞭解,在後臺線程上運行10個查詢並等待它們會暫時阻塞11個線程。這可能是好的,或者不是,這取決於你期望的併發操作的數量。

我建議你做一些關於異步IO擴展性好處的研究,以便更好地理解使用它。請記住,異步需要付出代價:開發速度更慢,併發錯誤更多。

瞭解,異步IO與僅使用線程池(Task.Run)不同。線程池不是無線程的,而異步IO根本不使用任何線程。甚至不是由運行時管理的「不可見」線程。

我經常發現的是:如果你不得不問,你不需要它。

0

Task.WhenAllTask.WaitAll的非阻塞等價物,沒有看到您的代碼,我想不出爲什麼它不起作用的任何理由,並不會更好。但請注意,Task.WhenAll本身返回Task,您必須await。是你做的嗎?

+0

您是否必須阻止WCF方法?服務上下文與Http上下文?不知道,我應該再試一次,但想看看這些意見是在這裏的WCF使用。 Thx – Neal

+0

不,看起來有一個[問題](http://stackoverflow.com/questions/12797091/operationcontext-current-is-null-after-first-await-when-using-async-await-in- wcf)'OperationContext'在'await'之後爲空,但是如果你需要它,我會遵循該鏈接中的簡單建議並手動捕獲它。比阻塞所有這些線程好得多。 –