在C#中创建空闲循环的好方法?

时间:2009-09-14 09:50:51

标签: c# .net busy-loop

我有一个应用程序,它设置了一个FileSystemWatcher。它应该无限期地运行。

让它在空闲循环中运行的最佳方法是什么?

我正在做

FileSystemWatcher watch = ... //setup the watcher
watch.EnableRaisingEvents = true;
while (true) 
{
    Thread.Sleep(int.MaxValue);
}

似乎有效(即捕获事件并且不会在繁忙的循环中使用核心)。

还有其他成语吗?这种方法有什么问题吗?

5 个答案:

答案 0 :(得分:9)

FileSystemWatcher.WaitForChanged 阻止 (同步)。 绝对 不需要空闲循环,尤其是因为您正在处理事件。注意EnableRaisingEvents默认为true。因此,您所要做的就是将组件添加到表单中。没有空闲循环。没有线程,因为组件负责处理。

我知道您正在使用控制台应用程序。因此,您可以创建以下循环。同样,不需要空闲循环。该组件负责处理所有细节。

    Do
        Dim i As WaitForChangedResult = Me.FileSystemWatcher1.WaitForChanged(WatcherChangeTypes.All, 1000)
    Loop Until fCancel

[update]“注意EnableRaisingEvents默认为true。”根据Microsoft源代码,只有将FileSystemWatcher组件拖放到设计器上时才会出现这种情况。如下图所示:

    /// <internalonly/>
    /// <devdoc>
    /// </devdoc>
    [Browsable(false)] 
    public override ISite Site {
        get { 
            return base.Site; 
        }
        set { 
            base.Site = value;

            // set EnableRaisingEvents to true at design time so the user
            // doesn't have to manually. We can't do this in 
            // the constructor because in code it should
            // default to false. 
            if (Site != null && Site.DesignMode) 
                EnableRaisingEvents = true;
        } 
    }

[update]在WaitForChanged语句之前和之后立即调用System.Threading.Monitor.Wait设置EnableRaisingEvents。

答案 1 :(得分:5)

正如我从你的评论中所理解的那样,你需要你的应用程序无限期地运行,它是一个由另一个可执行文件发送的控制台应用程序。

最好使用Console.ReadLine而不是循环。 或使用Monitor.Wait方法无限期地阻止线程

object sync = new object();
lock(sync)
Monitor.Wait(sync);

答案 2 :(得分:2)

Thread.Sleep()会做你想要的。但基本上你应该阻止使用一种OS方法来唤醒你想要的策略。例如。一个Console.ReadLine()或一个被你的事件处理程序击中的互斥锁消失。

你不应该杀死你的应用程序让它关闭。

如果您将代码嵌入到表单中,那么至少可以很好地杀死表单,并在不使用时加载合理的操作系统。

答案 3 :(得分:2)

如果你将这个循环运行的线程标记为后台线程(Thread.IsBackground property)那么它应该可以正常工作(程序将在所有非后台线程终止时退出)

答案 4 :(得分:0)

我不明白...... 为什么要和空闲循环?您想让您的应用程序无限期运行吗?

那么,为什么不创建Windows服务或可以在系统托盘中运行的应用程序?

然后,我要做的是创建一个只执行此操作的类:

public class Foo
{
   private FileSystemWatcher _fs;

   private volatile bool _stopped = false;

   public Foo()
   {
       _fs = new FileSystemWatcher();
       ...
   }

   public void Start()
   {
       _stopped = false;
       Thread t = new Thread (new ThreadStart(DoWork));
       t.Start();
   }

   private void DoWork()
   {
       while( !_stopped )
       {
           Thread.Sleep(1);
       }
   }

   public void Stop()
   {
       _stopped = true;
   }

}