我有想要它执行每个代码然后等待然后执行下一个代码的程序
这是我的代码:
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
如果我想编写一个简单的伪代码,它将是这样的:
for each item in msg
print(item)
wait one second
next item
最佳答案
您需要将该方法标记为异步。
for each item in msg
print(item)
await Task.Delay(1000)//Await a second
next item
对于框架限制,如果您不能使用异步功能,则必须使用计时器或其他某种机制来实现。
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)
将返回一个Task
,它将在提供的毫秒数(在本例中为1000)后最终完成。我们正在等待(异步等待)该任务。要启用Await
功能,您需要将该方法标记为Async
。这将指导您async/await的工作方式。
对于.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();
}
}
}
用例:
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();
}
代码非常简单,我相信不需要任何解释:)如果有任何疑问,请删除注释。
Enumerate
方法返回一个任务,因此您可以等待在它上面,或者附上延续或其他内容。 (您可以添加
取消功能等)。
UI线程(提供SynchronizationContext)(如果提供),以便您
可以轻松地在回调中更新UI。
P.S:对C#代码表示歉意,基本上是C#家伙,要在Vb.Net中编写代码,我需要几天的时间:
关于vb.net - 在每个循环上等待一秒钟,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22112036/