正确的方式有无尽的等待

时间:2022-01-12 11:04:35

So I have a program that has a list of timers. Each of the timers has a tick event and lets just say for example, i have 10 timers started (all are in the List).

所以我有一个有定时器列表的程序。每个计时器都有一个tick事件,我只想说,例如,我有10个计时器启动(所有计时器都在列表中)。

What is the best way to sit forever (or until i tell it to stop)? Should I just have a while loop?

永远坐着的最佳方式是什么(或直到我告诉它停止)?我应该有一个while循环吗?

foreach(Timer t in _timers)
{
   t.Start();
}

while(true)
{
   Application.DoEvents();
   System.Threading.Thread.Sleep(5000);
}

I have a feeling that this isn't the best way...

我觉得这不是最好的方式......

-- Update Here's my entire program:

- 更新这是我的整个计划:

public static void Main()
{
  // set some properties and set up the timers

    foreach(Timer t in _timers)
    {
       t.Start();
    }

    while(true)
    {
       Application.DoEvents();
       System.Threading.Thread.Sleep(5000);
    }
}

Thats it. There is no UI, there's nothing else. If I don't have the while loop, then the program just finishes.

而已。没有UI,没有别的。如果我没有while循环,那么程序就完成了。

4 个解决方案

#1


Use an EventWaitHandle or array of EventWaitHandles to block thread execution by using the WaitOne() or WaitAll() methods.

使用EventWaitHandle或EventWaitHandles数组通过使用WaitOne()或WaitAll()方法来阻止线程执行。

http://msdn.microsoft.com/en-us/library/kad9xah9.aspx

So for example

所以举个例子

ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne();

will wait for eternity.

将等待永恒。

edit

Since you're making a service, you might want to read this article.

由于您正在提供服务,因此您可能希望阅读本文。

#2


By the Application.DoEvents, I assume you are on a UI thread here. It is never a good idea to keep the UI thread active (even with DoEvents). Why not just start the timers and release control back to the message pump. When the events tick it'll pick up the events.

通过Application.DoEvents,我假设你在这里的UI线程。保持UI线程处于活动状态永远不是一个好主意(即使使用DoEvents)。为什么不启动计时器并将控制权释放回消息泵。当事件发生时,它会选择事件。

Why do you want to loop?

你为什么要循环?


Re the update; which Timer are you using? If you use System.Timers.Timer (with the Elapsed event) then it isn't bound to the message-loop (it fires on a separate thread): you can just hang the main thread, perhaps waiting on some exit condition:

重新更新;您正在使用哪个计时器?如果您使用System.Timers.Timer(使用Elapsed事件),那么它不会绑定到消息循环(它在单独的线程上触发):您可以挂起主线程,也许等待一些退出条件:

using System;
using System.Timers;
static class Program {
    static void Main() {
        using (Timer timer = new Timer()) {
            timer.Interval = 2000;
            timer.Elapsed += delegate {
                Console.Error.WriteLine("tick");
            };
            timer.Start();
            Console.WriteLine("Press [ret] to exit");
            Console.ReadLine();
            timer.Stop();
        }
    }
}

#3


You could wait on a condition variable, or select() on a socket.

您可以等待条件变量,或者在套接字上选择()。

#4


Depending on how you're exiting the program, you might consider using only nine timers and have the tenth activity part of the main thread of your code.

根据您退出程序的方式,您可能会考虑仅使用九个计时器,并将第十个活动作为代码主线程的一部分。

Each of those timers is a separate thread and should be handled carefully.

每个计时器都是一个单独的线程,应该小心处理。

DoEvents is considered 'evil' and should be avoided. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx

DoEvents被认为是“邪恶的”,应该避免。 http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx

#1


Use an EventWaitHandle or array of EventWaitHandles to block thread execution by using the WaitOne() or WaitAll() methods.

使用EventWaitHandle或EventWaitHandles数组通过使用WaitOne()或WaitAll()方法来阻止线程执行。

http://msdn.microsoft.com/en-us/library/kad9xah9.aspx

So for example

所以举个例子

ManualResetEvent mre = new ManualResetEvent(false);
mre.WaitOne();

will wait for eternity.

将等待永恒。

edit

Since you're making a service, you might want to read this article.

由于您正在提供服务,因此您可能希望阅读本文。

#2


By the Application.DoEvents, I assume you are on a UI thread here. It is never a good idea to keep the UI thread active (even with DoEvents). Why not just start the timers and release control back to the message pump. When the events tick it'll pick up the events.

通过Application.DoEvents,我假设你在这里的UI线程。保持UI线程处于活动状态永远不是一个好主意(即使使用DoEvents)。为什么不启动计时器并将控制权释放回消息泵。当事件发生时,它会选择事件。

Why do you want to loop?

你为什么要循环?


Re the update; which Timer are you using? If you use System.Timers.Timer (with the Elapsed event) then it isn't bound to the message-loop (it fires on a separate thread): you can just hang the main thread, perhaps waiting on some exit condition:

重新更新;您正在使用哪个计时器?如果您使用System.Timers.Timer(使用Elapsed事件),那么它不会绑定到消息循环(它在单独的线程上触发):您可以挂起主线程,也许等待一些退出条件:

using System;
using System.Timers;
static class Program {
    static void Main() {
        using (Timer timer = new Timer()) {
            timer.Interval = 2000;
            timer.Elapsed += delegate {
                Console.Error.WriteLine("tick");
            };
            timer.Start();
            Console.WriteLine("Press [ret] to exit");
            Console.ReadLine();
            timer.Stop();
        }
    }
}

#3


You could wait on a condition variable, or select() on a socket.

您可以等待条件变量,或者在套接字上选择()。

#4


Depending on how you're exiting the program, you might consider using only nine timers and have the tenth activity part of the main thread of your code.

根据您退出程序的方式,您可能会考虑仅使用九个计时器,并将第十个活动作为代码主线程的一部分。

Each of those timers is a separate thread and should be handled carefully.

每个计时器都是一个单独的线程,应该小心处理。

DoEvents is considered 'evil' and should be avoided. http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx

DoEvents被认为是“邪恶的”,应该避免。 http://msdn.microsoft.com/en-us/library/system.windows.forms.application.doevents.aspx