在VB.net中继续代码之前等待0.5秒。

30

我有一个代码,想让它在中间某处停顿一下再继续执行。 在WebBrowser1.Document.Window.DomWindow.execscript("checkPasswordConfirm();","JavaScript")之后, 我想让它等待0.5秒钟,然后执行代码的其余部分。

    WebBrowser1.Document.Window.DomWindow.execscript("checkPasswordConfirm();","JavaScript")

    Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
    For Each webpageelement As HtmlElement In allelements
        If webpageelement.InnerText = "Sign Up" Then
            webpageelement.InvokeMember("click")
        End If
    Next

2
你怎么知道那会够长? - Cody Gray
因为我已经测试过了。这似乎足够了,但当 JavaScript 函数完成时会更好。 - koolboy5783
3
如果我的网络连接速度较慢或者我的计算机JavaScript解释器较慢呢?我的意思是,假设特定的时间值很少是一个好的解决方案。当然也不是一个稳健的解决方案。 - Cody Gray
1
@koolboy5783:所以你找到了实证证据,证明这个解决方案适用于你的情况。然而,这并不证明它在长期内有效。就像Cody提到的那样,很可能很快就会出现问题。如果你在等待事件的发生,最好在代码中进行标识-这样更容易进行调试和故障排除。 - Victor Zakharov
12个回答

60

您需要使用System.Threading.Thread.Sleep(毫秒数)

WebBrowser1.Document.Window.DomWindow.execscript("checkPasswordConfirm();","JavaScript")

Threading.Thread.Sleep(500) ' 500 milliseconds = 0.5 seconds

Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
    If webpageelement.InnerText = "Sign Up" Then
        webpageelement.InvokeMember("click")
    End If
Next

2
每当我这样做时,程序首先会冻结,然后才执行代码。 - koolboy5783
1
我知道。你有两个选项,要么冻结线程,要么使用计时器(chipperyman573的建议)... - Sam
我正在使用VB.NET的Winform应用程序,这不会导致我的程序崩溃。我正在等待SQL更新完成,但像@Neolisk提到的那样,事件处理可能是最好的方法。我认为我可能需要创建一个问题来解决这个问题,因为我目前在StackOverflow上没有看到任何发布的内容。 - eniacAvenger

16
这个问题比较老,但以下是另一种回答方法,因为它对其他人有用: thread.sleep 不是一个好的等待方法,因为通常它会冻结软件直到完成时间,这个函数更好:
   Imports VB = Microsoft.VisualBasic

   Public Sub wait(ByVal seconds As Single)
     Static start As Single
     start = VB.Timer()
     Do While VB.Timer() < start + seconds
       System.Windows.Forms.Application.DoEvents()
     Loop
   End Sub

上述函数在不冻结软件的情况下等待特定时间,但会增加CPU使用率。
这个函数不仅不会冻结软件,而且也不会增加CPU使用率:
   Private Sub wait(ByVal seconds As Integer)
     For i As Integer = 0 To seconds * 100
       System.Threading.Thread.Sleep(10)
       Application.DoEvents()
     Next
   End Sub

wait函数参数中的second的值是以秒还是毫秒为单位? - Sunny Sandeep
@SunnySandeep 这里的单位是秒,因为如果 seconds = 2,那么我们会循环 2 * 100 = 200 次,而 200 * 10 (Sleep(..) 中的值) = 2000,总共就是 2 秒(以毫秒为单位)。 - Hille
Timers.Timer在实例不多的情况下是很好的选择,而且易于实现。但是如果需要使用多个Timers.Timer,执行速度会变慢。对于这种情况,Thread.Wait()(实现有点复杂)是一个不错的选择。我有经验,所以这么说。 - Raky

5
Imports VB = Microsoft.VisualBasic

Public Sub wait(ByVal seconds As Single)
    Static start As Single
    start = VB.Timer()
    Do While VB.Timer() < start + seconds
        System.Windows.Forms.Application.DoEvents()
    Loop
End Sub

%20+ 高CPU使用率 + 无延迟

Private Sub wait(ByVal seconds As Integer)
    For i As Integer = 0 To seconds * 100
        System.Threading.Thread.Sleep(10)
        Application.DoEvents()
    Next
End Sub

%0.1 的CPU使用率+高延迟


4
制作一个计时器,在它滴答作响时激活你想要的任何代码。确保在计时器代码的第一行中包含以下内容:
timer.enabled = false

用你给定的计时器名称替代"timer"。

然后在你的代码中使用如下内容:

   WebBrowser1.Document.Window.DomWindow.execscript("checkPasswordConfirm();","JavaScript")
timer.enabled = true
Dim allelements As HtmlElementCollection = WebBrowser1.Document.All
For Each webpageelement As HtmlElement In allelements
    If webpageelement.InnerText = "Sign Up" Then
        webpageelement.InvokeMember("click")
    End If
Next

0

在继续下一步之前,通过检查浏览器的就绪状态,我获得了更好的结果。这将不会执行任何操作,直到浏览器具有“完成”就绪状态。

Do While WebBrowser1.ReadyState <> 4
''' put anything here. 
Loop

0

Threading.Thread.SLeep(2000) 的问题是它会在我的 VB.Net 程序中优先执行。

Imports VB = Microsoft.VisualBasic

Public Sub wait(ByVal seconds As Single)
    Static start As Single
    start = VB.Timer()
    Do While VB.Timer() < start + seconds
        System.Windows.Forms.Application.DoEvents()
    Loop
End Sub

运行得非常完美。


0

建议的代码有缺陷:

Imports VB = Microsoft.VisualBasic

Public Sub wait(ByVal seconds As Single)
    Static start As Single
    start = VB.Timer()
    Do While VB.Timer() < start + seconds
        System.Windows.Forms.Application.DoEvents()
    Loop
End Sub

VB.Timer() 返回自午夜以来的秒数。如果在午夜前调用此函数,则返回值将接近一整天。 我建议采用以下方法:

Private Sub Wait(ByVal Seconds As Double, Optional ByRef BreakCondition As Boolean = False)
    Dim l_WaitUntil As Date
    l_WaitUntil = Now.AddSeconds(Seconds)
    Do Until Now > l_WaitUntil
        If BreakCondition Then Exit Do
        DoEvents()
    Loop
End Sub

当调用DoEvents时,可以将BreakCondition设置为true以取消waitloop,这可以从循环外部完成。


这种方法比sleep()方法要好得多,后者有太多的延迟。对于2秒的处理时间延迟,这种方法可以立即工作,而使用sleep方法的2秒延迟会导致大约10秒的延迟。此外,我设置了一个计时器,延迟5000毫秒,用于另一个子程序,每5秒触发一次以检查某些内容,而使用sleep方法的延迟相当于2秒乘以5秒(5000毫秒)计时器延迟。我认为它们在幕后互动并导致更长的延迟。 - user1493382

0
Static tStart As Single, tEnd As Single, myInterval As Integer
myInterval = 5 ' seconds
tStart = VB.Timer()
tEnd = myInterval + VB.Timer()
Do While tEnd > tStart
    Application.DoEvents()
    tStart = VB.Timer()
Loop

0

使用Threading.Thread.Sleep(5000)并导入Threading来等待5秒钟。


0
Public Sub WaitFor(Secs As Integer)
    Dim StartTime As DateTime = TimeOfDay
    Dim EndTime As DateTime = DateAdd(DateInterval.Second, Secs, StartTime)
    Do While StartTime < EndTime
        StartTime = TimeOfDay
    Loop
End Sub

当然,这仅适用于整秒,而不是部分秒。


考虑到问题的时间限制为0.5秒,建议提供处理毫秒而非整秒的解决方案会更好。 - Jen

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接