最简单的选择是使用这个模型:
public async void button1_Click(object sender, EventArgs args)
{
if(condition)
{
button.visible=true;
await Task.Delay(1000);
GotoMeasurementMode(3000);
await Task.Delay(3000);
query(device.Text);
await Task.Delay(7000);
StopMeasurement();
await Task.Delay(4000);
}
}
如果您无权访问 C# 5.0,则可以在 4.0 中执行此操作。您需要从自己的Delay
方法开始,因为 .NET 4.0 中不存在这种方法:
public static Task Delay(int milliseconds)
{
var tcs = new TaskCompletionSource<bool>();
var timer = new System.Threading.Timer(o => tcs.SetResult(false));
timer.Change(milliseconds, -1);
return tcs.Task;
}
使用它,我们现在可以编写:
Delay(1000)
.ContinueWith(t => GotoMeasurementMode(3000), TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(t => Delay(3000)).Unwrap()
.ContinueWith(t => query(device.Text), TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(t => Delay(7000)).Unwrap()
.ContinueWith(t => StopMeasurement(), TaskScheduler.FromCurrentSynchronizationContext())
.ContinueWith(t => Delay(4000)).Unwrap();
这与第一个片段将被编译成的代码非常相似,但显然第一个更漂亮,所以你应该尽可能使用它。
如果我们回到 C# 3.0,那么我们将无法访问Task
,这意味着我们又回到了使用计时器和回调。我们将从这个简单的辅助方法开始为我们处理管理任务:
public static void ExecuteIn(int milliseconds, Action action)
{
var timer = new System.Windows.Forms.Timer();
timer.Tick += (s, e) => { action(); timer.Stop(); };
timer.Interval = milliseconds;
timer.Start();
}
然后我们可以嵌套调用这个:
ExecuteIn(1000, () =>
{
GotoMeasurementMode(3000);
ExecuteIn(3000, () =>
{
query(device.Text);
ExecuteIn(7000, () => StopMeasurement());
});
});
虽然可以在 C# 3.0 中重新创建 a Task
(它不利用任何 4.0 语言功能)并且现有的库可以做到这一点,但这会涉及更多。