gpt4 book ai didi

.net - Task.Wait 不等待

转载 作者:行者123 更新时间:2023-12-01 05:18:04 24 4
gpt4 key购买 nike

我正在 vb.net 中开始一项新任务并等待一段时间。如果到那个时候任务还没有完成,我不想附加另一个任务作为延续,并且在另一个任务日志中记录了 task1 的执行时间。代码看起来或多或少是这样的:

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 任务附加到它作为延续。
这会导致这样的日志:
任务超时!超时时间: 10000 毫秒 ,耗时: 3371 毫秒
我有异常登录等,可以确认没有异常也没有错误。看起来就像 task.Wait(timeout)随机决定不等待......
以前有人遇到过吗?有什么解决办法吗?谢谢你的时间。

- - 编辑 - -

好的,所以我通过添加秒表并输出要调试的内容进行了实验:
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里面之前好像有很大的延迟。开始(swElapsed 开始)。
所以我发现 TaskFactory.StartNew()并不总是立即启动任务,如果线程池已满,任务将被放入队列中。虽然这是可以理解的,但 Task.Wait()显然没有考虑到这一点,因此任务可能会在等待完成后开始。我现在正在阅读 TaskScheduler 以检查我是否可以增加线程池以适应所有任务,或者做其他事情来解决问题(但我不知道现在是什么,呵呵)......如果你们有任何想法让我知道 :)

- - 编辑 - -

女士们先生们的另一个更新。线程池填满的问题已经解决(最初)通过提示创建新任务 TaskCreationOptions.LongRunning .这根据 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 多个任务)。

最佳答案

您可以按如下方式更改您的功能:

Private Function _GetAvailability(requests As RequestsCollection) As Tuple(Of Availability, Long)
Dim swElapsed As New StopWatch = StopWatch.StartNew()
'do some stuff here (CPU heavy and network related)
swElapsed.Stop()
Debug.WriteLine("Elapsed: " & swElapsed.ElapsedMilliseconds)
Return Tuple.Create(xxx,swElapsed.ElapsedMilliseconds)
End Function

然后始终附加您的延续方法:
task.ContinueWith(Sub(previous)
If previous.Item2 > timeout
LogAvailabilityTimeout(timeout, previous.Item2)
End If
End Sub, TaskContinuationOptions.OnlyOnRanToCompletion)

这至少应该解决您的报告问题。

关于.net - Task.Wait 不等待,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18527907/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com