我正在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()中的秒表中拉出并分配给类变量 –
一个类变量,你说。它的价值可能被其他任务覆盖吗? –