use*_*819 0 c# multithreading timer winforms
我在Windows窗体C#中使用Thread.Sleep.使用哪个导致没有响应表格.使用Timer也不符合我的目的.
示例代码:
if(......) // There are many if with difrent components and many Thread.sleep
{
button.visible=true;
Thread.sleep(1000);
GotoMeasurementMode(3000);
Thread.sleep(3000);
query(device.Text);
Thread.sleep(7000);
StopMeasurement();
Thread.sleep(4000);
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码会导致形式无响应.使用Timer会产生嵌套计时器.而且在我的情况下并不成功.请告诉我Windows窗体的另一种选择.想要命令之间的特定暂停.
Ser*_*rvy 13
最简单的选择是使用此模型:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您无法访问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;
}
Run Code Online (Sandbox Code Playgroud)
使用它我们现在可以写:
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();
Run Code Online (Sandbox Code Playgroud)
这与第一个代码片段编译成的代码非常相似,但显然第一个代码段更漂亮,所以你应该尽可能地使用它.
如果我们回到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();
}
Run Code Online (Sandbox Code Playgroud)
然后我们可以嵌入调用:
ExecuteIn(1000, () =>
{
GotoMeasurementMode(3000);
ExecuteIn(3000, () =>
{
query(device.Text);
ExecuteIn(7000, () => StopMeasurement());
});
});
Run Code Online (Sandbox Code Playgroud)
虽然可以Task在C#3.0中重新创建一个(它没有利用任何4.0语言功能),并且有现有的库可以做到这一点,但这将涉及更多.