vb.net 在每个循环中等待一秒钟
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/22112036/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Wait for a second on each loop
提问by EmPlusPlus
I have program that I want it to do each code then wait and then do next code here is my codes:
我有一个程序,我希望它执行每个代码然后等待然后执行下一个代码,这是我的代码:
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim msg() As String = {"a", "b", "c", "e"}
For Each item In msg
MessageBox.Show(item)
Next
End Sub
if I want to write a simple pseudocode, it would be like this:
如果我想写一个简单的伪代码,它会是这样的:
for each item in msg
print(item)
wait one second
next item
回答by Sriram Sakthivel
You need to mark the method as async.
您需要将该方法标记为异步。
for each item in msg
print(item)
await Task.Delay(1000)//Await a second
next item
For framework restrictions if you cant use async feature you'll have to do that with timer or some other mechanism.
对于框架限制,如果您不能使用异步功能,则必须使用计时器或其他一些机制来做到这一点。
Private Async Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim msg() As String = {"a", "b", "c", "e"}
For Each item In msg
MessageBox.Show(item)
Await Task.Delay(1000)//Await a second
Next
End Sub
Task.Delay(1000)will return a Taskwhich will eventually reach completion after provided milliseconds(1000 in this case). We're awaiting(asynchronously waiting) on that task. To enable Awaitfeature you need to mark the method as Async.
Task.Delay(1000)将返回一个Task最终在提供的毫秒后完成(在这种情况下为 1000)。我们正在等待(异步等待)该任务。要启用Await功能,您需要将该方法标记为Async.
This will guide you how async/awaitworks.
这将指导您async/await是如何工作的。
For .net 4.0, and who can't use Bcl.Async pack following code will help.
对于 .net 4.0,以及不能使用 Bcl.Async 包的人,以下代码会有所帮助。
public class PeriodicEnumerator<T>
{
private IEnumerable<T> sequence;
private Action<T> action;
private int period;
private System.Threading.Timer timer;
private SynchronizationContext synchronizationContext;
private IEnumerator<T> enumerator;
private TaskCompletionSource<object> completionSource = new TaskCompletionSource<object>();
public PeriodicEnumerator(IEnumerable<T> sequence, Action<T> action, int period)
: this(sequence, action, period, null)
{
}
public PeriodicEnumerator(IEnumerable<T> sequence, Action<T> action, int period, SynchronizationContext synchronizationContext)
{
this.sequence = sequence;
this.action = action;
this.period = period;
this.synchronizationContext = synchronizationContext;
this.timer = new System.Threading.Timer(TimerCallback);
}
public Task Enumerate()
{
if (this.enumerator != null)
{
throw new InvalidOperationException("Enumeration already started");
//To avoid multiple enumerations, better create new instance
}
enumerator = sequence.GetEnumerator();
timer.Change(0, Timeout.Infinite);
return completionSource.Task;
}
private void TimerCallback(object state)
{
if (!enumerator.MoveNext())
{
completionSource.SetResult(null);
timer.Dispose();
return;
}
try
{
T current = enumerator.Current;
if (synchronizationContext != null)
{
synchronizationContext.Send((x) => action(current), null);
}
else
{
action(current);
}
timer.Change(period, Timeout.Infinite);
}
catch (Exception ex)
{
completionSource.SetException(ex);
timer.Dispose();
}
}
}
Usecase:
用例:
static void ConsoleAppSample()
{
var periodicEnumerator = new PeriodicEnumerator<int>(Enumerable.Range(1, 5), (x) => Console.WriteLine(x), 1000);
Task enumerationTask = periodicEnumerator.Enumerate();
enumerationTask.Wait();//Optionally wait for completion
Console.WriteLine("Completed");
Console.Read();
}
static void SynchronizationContextSample()//applicable for any UI apps
{
var periodicEnumerator = new PeriodicEnumerator<int>(Enumerable.Range(1, 5), (x) => textbox.Text = x.ToString(), 1000,SynchronizationContext.Current);
Task enumerationTask = periodicEnumerator.Enumerate();
Console.WriteLine("Completed");
Console.Read();
}
Code is pretty simple, I believe no explanation required :) If anything drop a comment.
代码非常简单,我相信不需要解释:) 如果有任何评论。
- Notice that
Enumeratemethod returns a task, so that you may wait on it, or attach a continuation or whatever. (You may add cancellation feature etc). - Also support for GUI applications to make sure callback is fired in UI thread(given SynchronizationContext) if any provided, so that you can update UI in callback easily.
- 请注意,该
Enumerate方法返回一个任务,以便您可以等待它,或者附加一个延续或其他任何东西。(您可以添加取消功能等)。 - 还支持 GUI 应用程序以确保在 UI 线程(给定 SynchronizationContext)中触发回调(如果提供),以便您可以轻松地在回调中更新 UI。
P.S: apologizes for c# code, am basically c# guy, It will take days for me to code in Vb.Net :p
PS:为 c# 代码道歉,我基本上是 c# 人,我需要几天时间在 Vb.Net 中编码:p
回答by Bhavik Ambani
You can do this by making thread sleep for some seconds as shown below
您可以通过让线程休眠几秒钟来做到这一点,如下所示
System.Threading.Thread.Sleep(1000);
回答by Shell
I have used thread in my code becuase sleep will hang the application.
我在代码中使用了线程,因为 sleep 会挂起应用程序。
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim thread As New System.Threading.Thread(AddressOf ShowMessage)
thread.IsBackground = True
thread.Start()
End Sub
Private Sub ShowMessage()
Dim msg() As String = {"a", "b", "c", "e"}
For each item As String In msg
MessageBox.Show(item)
System.Threading.Thread.Sleep(1000)
Next
End Sub

