while(true)或tcp listen:什么更有效率?

时间:2010-01-08 14:12:05

标签: c#

我希望我的程序能够持续等待触发器以执行下一个任务。

  1. 一种选择是汇集:使用无限循环,例如:而(真)
  2. OR,TCP侦听超时时间相对较高的端口。
  3. 我想知道这两种技术中的哪一种更有效率,同时让我的应用程序保持活力?

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

    此外,在.net winform应用程序中,我们使用Application.Run()方法使应用程序保持活动状态。如果有人知道这个方法在内部做什么分享。

    PS:我已经在这里考虑了msmq选项(相当于tcp listen)但是我不希望对msmq有依赖。

3 个答案:

答案 0 :(得分: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);

或者,您可以引入一个简单的布尔值并重用相同的事件。如果您想在停止之前确保处理所有任务,那么这实际上可能是首选。

答案 1 :(得分:3)

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

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

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

如果你关闭最后一个窗口时你的WinForms应用程序没有结束,那么很可能会有一些线程继续运行

答案 2 :(得分:0)

我会考虑将您的代码部分放入一个单独的线程中,让线程等待释放您的UI,让您的UI监听事件:

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...