我正在vb.net中啓動一個新任務並等待一段時間。如果到那時任務沒有完成,我不想將另一個任務作爲延續,並且在任務1的執行的另一個任務日誌執行時間內。代碼看起來像或多或少:Task.Wait不會等待
Dim task As Task(Of Availability) = task.Factory.StartNew(
Function() As Availability
Return _GetAvailability(requests)
End Function)
task.Wait(timeout)
If task.IsCompleted Then
MyBase.availability = task.Result
Else
task.ContinueWith(Sub(previous)
LogAvailabilityTimeout(timeout, elapsedTime)
End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
End If
出於某種原因偶爾task.Wait(timeout)
不會等待一定的時間和恰到好處通過跳過。因爲那時候任務沒有辦法完成,所以LogAvailabilityTimeout任務將作爲延續附加到它。
結果如下:
任務時間!超時時間:10000ms,已用時間:3371ms
我有異常記錄等等,可以確認沒有例外,沒有錯誤。這似乎是task.Wait(timeout)
隨機決定不要等待...
任何人都來過這個問題嗎?有沒有解決方案?謝謝你的時間。
---- ----編輯
好了,所以我也加入了秒錶和outputing東西調試做過一個實驗:
Dim swTemp As StopWatch = StopWatch.StartNew()
Dim task As Task(Of Availability) = task.Factory.StartNew(
Function() As Availability
Return _GetAvailability(requests)
End Function)
task.Wait(timeout)
swTemp.Stop()
Debug.WriteLine("Waited For: " & swTemp.ElapsedMilliseconds)
If task.IsCompleted Then
MyBase.availability = task.Result
Else
task.ContinueWith(Sub(previous)
LogAvailabilityTimeout(timeout, elapsedTime)
End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)
End If
的_GetAvailability
看起來或多或少這樣的:
Private Function _GetAvailability(requests As RequestsCollection) As Availability
Dim swElapsed As New StopWatch = StopWatch.StartNew()
'do some stuff here (CPU heavy and network related)
swElapsed.Stop()
Debug.WriteLine("Elapsed: " & swElapsed.ElapsedMilliseconds)
Me.elapsedTime = swElapsed.ElapsedMilliseconds
Return xxx
End Function
看起來這的確是等待10000,但似乎是一個很大的延遲的_GetAvailability
開始的內部(SWE前失效開始)。
所以我發現TaskFactory.StartNew()
並不總是立即啓動任務,如果線程池滿了,任務將被放入隊列中。雖然這是可以理解的,但Task.Wait()
顯然沒有考慮到這一點,所以任務可能在等待結束後開始。我正在閱讀有關TaskScheduler的內容,以檢查是否可以增加線程池以適應所有任務,或者採取其他措施解決問題(但我不知道現在是嘿嘿)如果你們有任何想法,請讓我知道:)
---- ----編輯
爲您女士和gentelmen另一個更新。線程池填充問題已經通過暗示創建新任務來解決(最初)。根據MS文檔,這提示TaskScheduler該任務可能會阻塞較長時間的線程池,在這種情況下,調度程序會創建一個額外的線程來適應此問題。這就是我現在火任務:
Dim task As Task(Of Availability) = task.Factory.StartNew(
Function() As Availability
Return _GetAvailability(requests)
End Function, TaskCreationOptions.LongRunning)
task.Wait(timeout)
由於這種變化的所有任務似乎他們正在開始執行(不被放入隊列)。這是在測試時,我發射了50個任務。我現在正在進行更多的負載測試(超過1000個任務)。
'timeout'是一個常數還是可能會被更新?另外,如何計算'elapsedTime'? –
timeout是一個從配置文件中取出的變量(它在代碼中的任何地方都沒有更新)。 elapsedTime從_GetAvailability()中的秒錶中拉出並分配給類變量 –
一個類變量,你說。它的價值可能被其他任務覆蓋嗎? –