【发布时间】:2011-04-19 23:34:03
【问题描述】:
我正在编写一个 TCP 服务器,它的核心是一段相当标准的 bind-listen-accept 代码,由 TcpListener 很好地封装。我正在开发中运行的代码现在工作,但我正在寻找有关我选择的线程模型的一些讨论:
// Set up the socket listener
// *THIS* is running on a System.Threading.Thread, of course.
tpcListener = new TcpListener(IPAddress.Any, myPort);
tpcListener.Start();
while (true)
{
Socket so = tpcListener.AcceptSocket();
try
{
MyWorkUnit work = new MyWorkUnit(so);
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler(DispatchWork);
bw.RunWorkerCompleted +=
new RunWorkerCompletedEventHandler(SendReply);
bw.RunWorkerAsync(work);
}
catch (System.Exception ex)
{
EventLogging.WindowsLog("Error caught: " +
ex.Message, EventLogging.EventType.Error);
}
}
我已经看到了关于选择哪种线程模型(BackgroundWorker、stock Thread 或 ThreadPool)的很好的描述,但没有一个适用于这种情况。 backgroundworker-vs-background-thread (第二个答案)是对每种优缺点的一个很好的总结。在上面的示例代码中,我选择了 BackgroundWorker,因为它很简单。是时候弄清楚这是否是正确的方法了。
这些是这个应用程序的细节,对于大多数类似事务的 TCP 服务器来说,它们可能是相当标准的:
- 不是 Windows 窗体应用程序。事实上,它作为 Windows 服务运行。
- (我不确定生成的工作是否需要成为前台线程。我现在将它们作为后台运行,一切正常。)
- 只要
Accept()循环获得循环,分配给线程的任何优先级都可以。 - 对于以后的
Abort()或其他什么,我不需要线程的固定 ID。 - 在线程中运行的任务很短——最多几秒钟。
- 可能有很多任务会很快进入这个循环。
- 如果我没有线程,拒绝(或排队)新工作的“优雅”方式会很好。
那么,哪种方法才是正确的呢?
【问题讨论】:
-
有人在Answer中建议了这种编码方法并删除了它。 stackoverflow.com/questions/62449/… 但也许不是。细节会很好。这是一个正常的线程,对吧?如果它死了,我的进程就死了吗?
标签: c# multithreading tcp