代码之家  ›  专栏  ›  技术社区  ›  Vinko Vrsalovic

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

  •  3
  • Vinko Vrsalovic  · 技术社区  · 15 年前

    我有一个应用程序,它设置了一个文件系统观察程序。它应该无限期地运行。

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

    我现在在做

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

    这似乎是可行的(即,捕捉事件,不会在繁忙的循环中耗尽核心)。

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

    5 回复  |  直到 15 年前
        1
  •  5
  •   Ahmed    15 年前

    正如我从您的评论中了解到的,您需要您的应用程序无限期地运行,并且它是一个控制台应用程序,由另一个可执行文件提供支持。

    最好使用console.readline而不是循环。 或者使用monitor.wait方法无限期地阻塞线程

    object sync = new object();
    lock(sync)
    Monitor.Wait(sync);
    
        2
  •  9
  •   AMissico    15 年前

    filesystemwatcher.waitforchanged是 舞台调度 (同步)。有 绝对地 不需要空闲循环,特别是因为您正在处理事件。注意:EnableRaisingEvents默认为true。因此,您所要做的就是将组件添加到表单中。没有空闲循环。没有线程,因为组件会处理这个问题。

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

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

    [更新]“注意,EnableRaisingEvents默认值为true。”根据Microsoft源代码,只有将FileSystemWatcher组件放到设计器中时,此值才为true。如下图所示:

        /// <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;
            } 
        }
    

    [更新]呼叫 WaitForChanged System.Threading.Monitor.Wait 声明。

        3
  •  2
  •   Spence    15 年前

    thread.sleep()将执行您想要的操作。但基本上,你应该阻止使用一个操作系统方法,它会唤醒你想要的策略。例如一个console.readline()或一个互斥体上,它被事件处理程序点击以离开。

    你不应该为了关闭你的应用程序而杀死它。

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

        4
  •  2
  •   chris166    15 年前

    如果将运行此循环的线程标记为后台线程( Thread.IsBackground property )然后它应该可以正常工作(当所有非后台线程终止时,程序将退出)

        5
  •  0
  •   Frederik Gheysels    15 年前

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

    那么,为什么不创建一个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;
       }
    
    }