Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vb.net 创建Application.DoEvents的等待延迟替代方案_Vb.net_Multithreading_Winforms_Timer_Doevents - Fatal编程技术网

Vb.net 创建Application.DoEvents的等待延迟替代方案

Vb.net 创建Application.DoEvents的等待延迟替代方案,vb.net,multithreading,winforms,timer,doevents,Vb.net,Multithreading,Winforms,Timer,Doevents,多年来,我使用以下方法在软件中造成延迟,例如: Wait(10000) Sub Wait(milliseconds) <here I get the current time> Do <here I loop until the current time passed in seconds and then exit this loop> Application.DoEvents() Loop End Sub

多年来,我使用以下方法在软件中造成延迟,例如:

Wait(10000)

Sub Wait(milliseconds)
    <here I get the current time>
    Do
         <here I loop until the current time passed in seconds and then exit this loop>
         Application.DoEvents()
    Loop
End Sub

如何在延迟后执行代码

有不同的方法可以在延迟后执行代码,也可以在延迟后异步执行代码。这里,我正在考虑一个计时器和异步/等待模式的简单实现

无论如何都应该避免调用
Application.DoEvent()
的循环


► 在一个或多个方法中使用延迟执行单个指令或代码:

您不能等待计时器,但可以使用一种方法来创建计时器,并在计时器引发其事件时执行操作,表示指定的间隔已过

下面的方法接受一个
delay
值和一个委托作为参数。
延迟用于设置计时器的间隔,该操作表示计时器滴答作响时将执行的代码(这里我使用的是a,因为您似乎指的是WinForms应用程序)

当需要在延迟后执行代码时,可以调用此方法

该操作可以是一个简单的指令:在这种情况下,
label1
的文本将在5秒后设置为“完成”,而UI线程继续其操作:

label1.text = "About to Start..."
Wait(5000, Sub() Me.label1.Text = "Done")
该操作也可以是一种方法:

Private Sub SetControlText(control As Control, controlText As String)
    control.Text = controlText
End Sub

' Elsewhere
Wait(5000, Sub() SetControlText(Me.label1, "Done"))
当然,
SetControlText()
方法可以执行更复杂的代码,并且可以选择设置计时器本身,调用
Wait()

► 使用

异步方法提供了一种方便的方法来执行以下操作: 在不阻塞调用者线程的情况下进行长时间运行的工作。呼叫者 异步方法可以在不等待异步消息的情况下恢复其工作 方法完成

简单地说,将添加到方法中,允许使用等待异步过程在执行后面的代码之前终止,而当前线程可以自由地继续其处理


▬ 请注意,
Async
修饰符始终应用于返回
任务
任务(某事物)
(某事物可以是方法可以返回的任何值/引用)的
函数()
当
Sub
void
)方法表示
事件处理程序时,它仅应用于
Sub()
。 这一点非常重要,要记住并毫无例外地应用(除非您非常清楚其含义)。▬

阅读相关文档(在上一个链接中)以及以下内容:



可以使用简单的
Async
方法延迟操作的执行:

Private Async Function Wait(delay As Integer, action As Action) As Task
    Await Task.Delay(delay)
    action?.Invoke()
End Function
这类似于计时器功能,并以类似的方式进行操作。不同之处在于,您可以
wait
此方法执行它异步运行的代码,并在方法返回后等待其完成以运行其他代码。 调用线程(此处为UI线程)将继续其操作,同时等待
Wait()
方法

假设,在
按钮中,单击
处理程序,我们希望执行一个操作(一个不返回值的方法)或一个函数(一个返回值的方法),下面的代码只应在该操作或函数返回后执行:

Private Async Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
    Await Wait(5000, New Action(Sub() Me.label1.Text = "Done"))
    Await Wait(5000, Nothing)
    ' (...)
    ' ... More code here. It will execute after the last Await completes
End Sub
在这里,我们指示等待5秒钟,然后将标签文本设置为一个值,再等待5秒钟,什么也不做,然后执行下面的代码

如果我们不需要执行操作,我们可以简单地使用:

我们还可以使用Async/Await等待在中运行的任务完成,调用Lambda表达式执行代码:
(举个例子,我们不应该使用线程池线程来完成如此简单的任务)

另见方法:

创建一个继续,当目标 任务完成


计时器怎么了?你试了哪个定时器?你能使用任务吗?也就是说,有一个
async
函数,您可以等待并调用
Task.Delay()
?您可以将延迟值和
Action()
Func()
传递给该方法(异步或非异步)。顺便说一句,如果您可以使用async stuff,
Wait(5000)
可以通过
Wait Task.Delay(5000)
本地设置。感谢您的响应。我从未使用过tasks或async,我在网上看到的只是C语言代码,所以我不理解。我确实尝试过计时器,但它不会循环或等待直到它完成,直到我调用计时器后它运行代码。label1.text=“DONE”只应在5秒后运行。我可以使用tasks或async thingy创建一个循环,而不冻结应用程序,同时为其提供一个应用程序。doevents替代方案,以便我可以同时执行其他操作吗?您使用的是什么版本的Visual Studio?您至少需要VS 2012才能使用async/await。我使用的是VS 2019。只是不知道如何使用aync并等待。因此,这些2我可以创建一个循环,直到计时器完成等等?主要的一点是根本不使用循环<代码>等待
允许在执行后续代码之前等待异步过程终止,而当前线程可以继续其处理。您不能使用计时器来执行此操作,但可以使用计时器来执行操作。我将发布几个例子。与此同时,看看吉米,首先,你很了不起。我的意思是你的详细回答,绝对令人惊讶!非常感谢你。我确实尝试了:DelayWithTimer(5000,Sub()Me.Label1.Text=“Done”),并注意到它的工作原理与计时器一样。它没有循环。所以技术上我可以用定时器完成同样的事情。这就是问题所在。我不想每次需要暂停时都跳转到不同的潜艇。如果我有一个SUB,它支持执行很多任务,例如使用webbrowser进行网页抓取,它需要在过程中等待几次,直到完成或加载某项操作。因此,我必须有某种类型的循环。我真的
Private Async Function Wait(delay As Integer, action As Action) As Task
    Await Task.Delay(delay)
    action?.Invoke()
End Function
Private Async Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
    Await Wait(5000, New Action(Sub() Me.label1.Text = "Done"))
    Await Wait(5000, Nothing)
    ' (...)
    ' ... More code here. It will execute after the last Await completes
End Sub
Private Async Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
    label1.text = "About to Start..."
    Await Task.Delay(5000)
    label1.Text = "Done"
    ' (...)
    ' ... More code here. It will execute after the last Await completes
End Sub
Private Async Sub button1_Click(sender As Object, e As EventArgs) Handles button1.Click
    label1.text = "About to Start..."
    Await Task.Run(Async Function()
                       Await Task.Delay(5000)
                       BeginInvoke(New Action(Sub() Me.label1.Text = "Done"))
                   End Function)
    ' (...)
    ' ... More code here. It will execute after the last Await completes
End Sub