2010-01-08 83 views
2

我希望我的程序能够持续等待触发器以执行下一个任务。while(true)或tcp listen:什么更有效?

  1. 一个选项是池化:使用无限循环例如while(true)
  2. 或者,TCP侦听具有相对较高超时的端口。

我想知道这两种技术中的哪一种会更高效,我的应用程序也保持活着吗?

我觉得正在执行while(true)会是一个杀手,而tcp listen可能是一个健康选项,因为tcp listen会使用硬件中断?

另外,在.net winform应用程序中,我们有Application.Run()方法来保持应用程序的活动。如果有人知道这种方法可以在内部分享。

PS:我已经在这里考虑msmq选项(这相当于tcp侦听),但我不想依赖于msmq。

+0

关于'也'部分:请作出一个单独的问题。 – 2010-01-08 14:24:01

+4

你到底在等什么?如果您正在等待TCP连接,那么最好听,否则其中一个等待对象,例如AutoResetEvent,会更好。对于WaitHandles,请参阅http://www.yoda.arachsys.com/csharp/threads/waithandles.shtml – Ryan 2010-01-08 14:29:11

回答

5

除非您实际上正在等待TCP/IP端口上发生的事情,否则您不应该(ab)使用Listen

一种有效的方法是AutoResetEvent,当您想要触发任务处理时发出信号。这将使你的线程睡眠,直到它需要做某事,没有任何投票。

class TaskProcessor 
{ 
    AutoResetEvent newTaskHandle = new AutoResetEvent(false); 
    Queue<Task> taskQueue = new Queue<Task>(); 
    object syncRoot = new object(); 

    public void ProcessTasks() 
    { 
     while (true) 
     { 
      newTaskHandle.WaitOne(); 

      Task task = null; 

      lock (syncRoot) 
      { 
       if (taskQueue.Count > 0) 
       { 
        task = taskQueue.Dequeue(); 
       } 
      } 

      // Do task 
     } 
    } 

    public void AddTask(Task task) 
    { 
     lock (syncRoot) 
     { 
      taskQueue.Enqueue(task); 
      newTaskHandle.Set(); 
     } 
    } 
} 

这可能会引发如何中止处理任务的问题。您可以使用多单WaitHandler(从继承的AutoResetEvent),并等待任何人的出现:

WaitHandle[] handles = new WaitHandle[] { newTaskHandle, stopHandle }; 

int signalledHandle = WaitHandle.WaitAny(handles); 

或者,你可以介绍一个简单的布尔和重复使用相同的事件。如果你想确保在停止之前处理所有的任务,那实际上可能是可取的。

+0

我认为他们需要为这样的答案创建一个名为“Vote Squatter”的“新占位符”。:) – 2010-01-08 14:37:11

+1

约翰:事实上,有时候看到最好的答案是稍后添加并且没有得到任何*票,有时会有点令人伤心,因为人们只会读到前几个。这就是为什么我养成了快速提供简短答案的习惯,然后我将其扩展。 – Thorarin 2010-01-08 14:58:16

3

这个触发器的来源是什么?相同的应用程序,相同的PC,网络?

相同的应用程序:使用AutoResetEvent 在同一台PC上的另一种应用:使用MutexSemaphore

是TCP听会是更好的选择,当触发源是另一台机器。

如果您的WinForms,当你关闭最后一个窗口最有可能的侯应用程序没有结束有一些线程保持运行

+0

使用已命名的Mutex进行进程间同步的好处。真的有很多可能性。一些额外的输入将阻止必须解释它们:) – Thorarin 2010-01-08 15:15:31

0

我会考虑把你的代码段到一个单独的线程,让线程做的等待释放你的用户界面,只需让你的用户界面监听事件:

var tcpConnectionMade = new AutoResetEvent(false); 
System.Threading.ThreadPool.QueueUserWorkItem(delegate 
{ 
    // listen for TCP connection 
    ... 
    // once connected 
    tcpConnectionMade.Set(); 
}); 

// wait for TCP connection 
WaitHandle.WaitOne(tcpConnectionMade); 

// do something when connected... 
相关问题