我希望我的程序能够持续等待触发器以执行下一个任务。
我想知道这两种技术中的哪一种更有效率,同时让我的应用程序保持活力?
我觉得执行while(true)会成为杀手而tcp listen可能是一个健康选项,因为tcp listen会使用硬件中断吗?
此外,在.net winform应用程序中,我们使用Application.Run()方法使应用程序保持活动状态。如果有人知道这个方法在内部做什么分享。
PS:我已经在这里考虑了msmq选项(相当于tcp listen)但是我不希望对msmq有依赖。
答案 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上的另一个应用程序:使用Mutex
或Semaphore
是当触发源是另一台机器时,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...