[英]How do I wait to Timer finish and then return from function?
I want to wait to a timer finish and then return from a function. 我想等到计时器完成然后从函数返回。 I tried this:
我试过这个:
while(timer1.Enabled)
{
Application.DoEvents();
}
return value;
But it didn't work and the function returned before the timer really finished. 但它没有工作,函数在计时器真正完成之前返回。 Here's the full function:
这是完整的功能:
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
int[] foo()
{
do_something1();
int[] some_value;
timer1.Interval = 1000;
timer1.Tick += new EventHandler(delegate(object o, EventArgs ea)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
timer1.Stop();
baa(some_value);
}
});
timer1.Start();
while (timer1.Enabled)
{
Application.DoEvents();
}
return some_value;
}
I think what you actually want is to wait until the browser is ready. 我认为你真正想要的是等到浏览器准备好了。 If so you can use a loop like this, and instead of
Application.DoEvents()
I recommend using async/await
feature: 如果是这样,你可以使用这样的循环,而不是
Application.DoEvents()
我建议使用async/await
功能:
while(browser.ReadyState != WebBrowserReadyState.Complete)
{
// you need to make your method async in order to use await
await Task.Delay(1000);
}
// do your job
Or better you can handle DocumentCompleted
event of WebBrowser. 或者你可以更好地处理WebBrowser的
DocumentCompleted
事件。
I will not go into how good or bad this approach is. 我不会讨论这种方法有多好或多坏。 But you can simply do this with a flag.
但你可以用旗帜做到这一点。
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
int[] foo()
{
do_something1();
int[] some_value;
bool doneWaiting = false;
timer1.Interval = 1000;
timer1.Tick += new EventHandler(delegate(object o, EventArgs ea)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
timer1.Stop();
baa(some_value);
doneWaiting = true;
}
});
timer1.Start();
while (!doneWaiting)
{
Application.DoEvents();
}
return some_value;
}
And you should probably put a Thread.Sleep in the while loop also. 你应该在while循环中放一个Thread.Sleep。
You can use a Thread
instead of a Timer
. 您可以使用
Thread
而不是Timer
。 Launch your waiting method in a Thread and simply wait it to finish with thread.IsAlive
. 在Thread中启动等待方法,然后等待它完成
thread.IsAlive
。
Your code must look like this: 您的代码必须如下所示:
int[] some_value;
int intervalle = 1000;
Thread thread = new Thread(new ThreadStart(delegate()
{
while (true)
{
Thread.Sleep(intervalle);
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
baa(some_value);
return;
}
}
}));
thread.Start();
while (thread.IsAlive)
{
Application.DoEvents();
}
return some_value;
Instead of using Await/Async and change the method signature you could use CountdownEvent
and threading. 而不是使用Await / Async并更改方法签名,您可以使用
CountdownEvent
和线程。
using System.Theading;
System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();
int[] foo()
{
int numberOfIterations = interval time * number of intervals; // initialize this to the proper number of times to decrement the counter. If we are decrementing every 1000 ms
CountdownEvent countDown = new CountdownEvemt(numberOfIterations);
do_something1();
int[] some_value;
timer1.Interval = 1000;
timer1.Tick += new EventHandler(delegate(object o, EventArgs ea)
{
if (browser.ReadyState == WebBrowserReadyState.Complete)
{
timer1.Stop();
baa(some_value);
// since this seems where you want to shut down the method we need to trigger the countdown
int countLeft = countDown.CurrentCount;
countDown.Signal(countLeft);
} else {
if(countDown.CurrentCount - 1 == 0) {
countDown.Reset(); // we don't want to finish yet since we haven't reached the proper end condition so reset the counter
}
countDown.Signal(); // will decrement the counter
}
});
timer1.Start();
countDown.Wait(); // will wait 'til the counter is at 0 before continuing
return some_value;
} }
The CountdownEvent
will block the current thread until the counter reaches 0. Since the Timer
class uses a ThreadPool
for its callback, that event will still fire and work as normal. CountdownEvent
将阻塞当前线程,直到计数器达到0.由于Timer
类使用ThreadPool
进行回调,因此该事件仍将触发并正常工作。
Simply put some_value into a class-level variable, then have the timer raise an event. 只需将some_value放入类级变量,然后让计时器引发一个事件。 Any function calling your function can (before the call) subscribe to the event and then handle it.
调用你的函数的任何函数都可以(在调用之前)订阅事件然后处理它。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.