2017-03-23 12 views
1

上下文:C#/ ASP.NET Core:這是.Wait()的正確用法嗎?

我們已經有了一個帶有接口和整個shabang的大型繼承樹。我們向一個工廠提供請求,創建適當的對象,然後我們調用一個DoStuff()方法,所有這些對象都暴露出來。該方法不返回任何內容,只是設置一些屬性。

問題:

只是一個單一的情況下,DoStuff()方法中,我們要調用一個異步方法,它周圍還有沒有辦法,因爲我們沒有過這種方法控制。重構整個繼承樹以使DoStuff()方法使用異步任務簽名並不是我們期待的。

我們沒有阻止線程,直到操作完成。

問:

我們的方法使用RunSynchronously()嘗試,但我們得到了以下錯誤:

System.InvalidOperationException: RunSynchronously may not be called on a task not bound to a delegate, such as the task returned from an asynchronous method. 
    at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource) 
    at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler, Boolean waitForCompletion) 

我們應該使用wait()的呢?

+0

是的,你可以使用'Wait()'或直接'Result'屬性來訪問返回值(如果存在)。這兩者將同步*等待任務完成。它也會阻塞執行線程。 –

+0

請注意,根據異步方法的實現 - 當您在asp.net應用程序中等待時,您可能會遇到死鎖。 – Evk

+0

雖然'Wait'可以工作,但我會推薦使用'GetAwaiter()。GetResult()',如果操作失敗,這將避免不必要的'AggregateException'包裝。 –

回答

0

這取決於你是否滿意缺點。這是一個Web應用程序,因此您希望儘可能使線程儘可能自由,但是通過使用.Wait(),您在異步方法內部需要任何線程的情況下還有一個線程不可用(或線程綁定的任務,而不是典型的Web應用程序)。

但是,如果這是您所害怕的,您將不會看到任何死鎖。 ASP.NET Core不使用非默認的SynchronizationContext,所以你不會鎖定,但會被警告,這是一個不能應付負載的滑坡,因爲這比同步版本更糟糕。

如果這是常規的ASP.NET如果任何await S中async法裏面都沒有使用ConfigureAwait(false)你會看到死鎖(它並不像黑與白作爲,但是這足夠近的真相)。

+0

是否安全(無鎖)在ASP.NET Core中使用.Result?並且是否有perf打擊? – benmccallum