开发者

while(true) or a tcp listen : what is more efficient?

开发者 https://www.devze.com 2022-12-16 00:16 出处:网络
I want my program to continuously wait for a trigger in order to perform the next task. One option is pooling: using an infinite loop e.g. while(true)

I want my program to continuously wait for a trigger in order to perform the next task.

  1. One option is pooling: using an infinite loop e.g. while(true)
  2. OR, Do TCP listen on a port with a relatively higher timeout.

I would like to know which one of these two techniques would be more efficient too keep my application alive?

I feel executing while(true) would be a killer and tcp listen might be a health option since the tcp listen would use hardw开发者_运维知识库are interrupt ?

Also, In .net winform applications we have the Application.Run() method that keeps the application alive. If anyone one knows what this method does internally pls share.

PS: I have already considered msmq option here ( which is equivalent to tcp listen ) but I do not want a dependency on msmq.


Unless you're actually waiting for something to happen on a TCP/IP port, you shouldn't (ab)use Listen.

An efficient method isAutoResetEvent that you signal when you want to trigger the processing of a task. This will make your thread sleep until it needs to do something, without any polling.

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();
        }
    }
}

This will probably raise the question how you can abort processing tasks. You can use more than a single WaitHandler (from which AutoResetEvent inherits) and wait for any of them to occur:

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

int signalledHandle = WaitHandle.WaitAny(handles);

Alternatively, you could introduce a simple boolean and reuse the same event. That might actually be preferrable if you want to make sure all tasks are processed before stopping.


What is this trigger's source ? Same application, same PC, network ?

Same application: use AutoResetEvent Another application on the same PC: use a Mutex or Semaphore

Yes TCP listen would be the better option when the trigger source is another machine.

If your WinForms application doesn't end when you close the last windows most likely hou have some thread left running


I would consider putting your section of code into a separate thread and let the thread do the waiting to free up your UI, just have your UI listen for the event:

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

精彩评论

暂无评论...
验证码 换一张
取 消