我必须每250毫秒测试一个布尔值,最多2秒,并且当它为真时停止。
试过这个,但Thread.Sleep对我来说不是一个很好的解决方案,因为它冻结了我的软件,等待更多的东西不会改变任何东西,因为布尔不会改变#&# 39;冷冻。
bool onLine = false;
Stopwatch chrono = new Stopwatch();
chrono.Start();
while (chrono.ElapsedMilliseconds < 2000)
{
if (!State().Equals(Online))
{
System.Threading.Thread.Sleep(250);
}
else
{
onLine = true;
operationCompleted();
break;
}
}
if (!onLine)
{
MessageBox.Show("Error");
}
如果某人有正确的实施,我不知道如何在计时器引发的事件中进行测试?
答案 0 :(得分:3)
currently accepted answer并未特别善用async
await
范例,并为不必复杂的事情引入了大量噪音。简单地使用Task.Run将同步,阻塞代码安排到ThreadPool上而不是升级到完全异步代码是一个半措施。
重写没有阻止代码和虚假Task.Run
的代码,它可以简单如下:
private async void button1_Click(object sender, EventArgs e)
{
bool onLine = false;
Stopwatch chrono = new Stopwatch();
chrono.Start();
while (chrono.ElapsedMilliseconds < 2000)
{
if (!State().Equals(Online))
{
await Task.Delay(250);
}
else
{
onLine = true;
break;
}
}
if (onLine)
{
operationCompleted();
}
else
{
MessageBox.Show("Error");
}
}
答案 1 :(得分:1)
不确定它在WPF中的样子,但是这里是如何在WinForms中完成的。请注意,按钮处理程序已标记为__init__.py
:
async
答案 2 :(得分:1)
以下是使用线程计时器的示例:
public class Foo
{
public System.Threading.Timer EventTimer
{
get;
set;
}
public long TimingInterval
{
get;
set;
}
public Foo()
{
EventTimer = new System.Threading.Timer(new TimerCallback(Foo.DoCheck),
this,
this.TimingInterval,
this.TimingInterval);
}
public void DoCheck()
{
//do check here
}
答案 3 :(得分:1)
这是使用计时器实现的一种方法。我们的想法是将间隔设置为您要检查的频率,并将超时变量设置为您要停止检查的时间。然后,在Tick
事件(触发每个间隔)中,进行在线检查,然后检查超时。
[更新了WPF以使用DispatcherTimer]
System.Windows.Threading.DispatcherTimer timer = new DispatcherTimer();
private DateTime timeout;
private void Window_Loaded(object sender, RoutedEventArgs e)
{
timeout = DateTime.Now.AddSeconds(2);
timer.Tick += Timer_Tick;
timer.Interval = TimeSpan.FromMilliseconds(250);
timer.Start();
}
private void Timer_Tick(object sender, EventArgs e)
{
if (State().Equals(Online))
{
onLine = true;
operationCompleted();
timer.Stop();
}
if (DateTime.Now > timeout)
{
timer.Stop();
MessageBox.Show("Error");
}
}
// rest of code omitted
答案 4 :(得分:0)
您可以使用BackgroundWorker
。
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += bw_DoWork;
bw.RunWorkerCompleted += bw_RunWorkerCompleted;
DoWork
的{{1}}事件处理程序在deditecated线程上执行,因此您的软件不会冻结。
BackgroundWorker
后台操作完成后,会发生private void bw_DoWork(object sender, DoWorkEventArgs e)
{
bool onLine = false;
Stopwatch chrono = new Stopwatch();
chrono.Start();
while (chrono.ElapsedMilliseconds < 2000)
{
if (!State().Equals(Online))
{
System.Threading.Thread.Sleep(250);
}
else
{
onLine = true;
break;
}
}
e.Result = onLine;
}
事件。您可以使用,将对象从RunWorkerCompleted
传递到DoWork
RunWorkerCompleted
。
e.Result
调用private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
bool onLine = (bool)e.Result;
if (onLine)
{
operationCompleted();
}
else
{
MessageBox.Show("Error");
}
}
时出现 DoWork
。您必须致电RunWorkerAsync
以启动bw.RunWorkerAsync();
。