要回答你的问题,两者兼而有之。您有线程和类在这些线程中运行。无论您使用 WCF、异步、套接字还是其他任何方式,您都将在线程中运行一些对象(或像使用异步一样在线程池中混洗)。使用 WCF,您可以配置并发模型,如果您必须等待 ack 或其他确认,您最好将其设置为多个线程,这样您就不会阻塞其他请求。
在您链接到作者的示例中,它AsyncCallback
用作告诉您套接字有数据的机制。但是,从MSDN你可以看到:
使用 AsyncCallback 委托在单独的线程中处理异步操作的结果
所以对于小规模的应用程序来说真的没有什么不同。像这样使用异步可以帮助您避免为每个线程分配堆栈空间,如果您要执行大型应用程序,这将很重要。但对于一个小型应用程序,我认为它只会增加复杂性。C# 4.5+ 和 F# 用 async 做了更干净的工作,所以如果你可以使用类似的东西,那么也许会去。
按照您的方式进行操作,您将拥有一个负责套接字管理的线程。它会坐下来接受新的连接。当它收到一个请求时,它将该套接字交给一个新的专用线程,然后该线程将坐在该套接字上并从中读取。该线程是您的客户端连接。我喜欢将读取的套接字客户端封装到一个基类中,该基类可以执行所需的低级 io,然后充当请求的路由器。即,当我收到请求 XYZ 时,我会请求 ABC。您甚至可以让它分派事件并在其他地方订阅这些事件(如在异步示例中)。现在您已经将客户端逻辑与套接字读取逻辑解耦了。
如果您使用 WCF 执行操作,则不需要套接字和所有额外处理,但您仍然应该知道调用是多线程的,并且在适用时正确同步您的应用程序。
对于 60 位客户,我认为您应该选择最适合您的。WCF 易于设置且易于使用,我会使用它,但套接字也很好。如果您担心正在运行的线程数,请不要担心。虽然运行太多线程是不好的,但大多数线程实际上会在等待 IO 时被阻塞。处于等待状态的线程不是由操作系统调度的,并且并不重要。更不用说等待很可能是在引擎盖下使用 io 完成端口,因此对于像您这样的小型应用程序,等待开销几乎可以忽略不计。
最后,我会选择最容易编写、维护和扩展的东西。