4

嗨,我想了解更多关于Async Callbacks如何与Sockets一起使用的信息。

假设从我的UI 线程我调用BeginRead方法并传入一个名为Read的回调。据我了解,BeginRead会产生一个新线程(线程 A),因此 UI 线程中的代码执行仍然可以继续。回调Read是在线程 A中执行的,对吗?它在EndRead处阻塞。

那么一旦回调结束,线程 A会自动关闭吗?

假设一旦调用回调,线程 A就会自行关闭:::

这是否意味着在线程 A结束之前调用另一个BeginRead是安全的?这个BeginRead将产生一个Thread B线程 B会无法执行或正确放置它,它是否会在某个时候终止,因为调用线程是线程 A已结束?或者线程根本不依赖于调用者?

4

2 回答 2

2

你在这里有一些误解。当您调用BeginRead您指定的回调时,将从应用程序的内部线程池中调用。通常不会启动新线程,尽管可能有一个 - 它取决于 .NET 的内部调度程序。

如果您在调试器中中断您的程序并转到“线程”视图,您应该会看到一堆名为 Worker 线程的线程。通常他们都在睡觉并等待工作。BeginRead这比每次你想阅读时都启动一个线程要快得多。相反,它使用这些在后台准备就绪的工作人员。

回调完成后,工作线程返回池中,为更多操作做好准备。

至于你的其他问题:

  • 回调不应阻塞在EndRead. 您的应用程序中不会有任何障碍。IO 数据将在缓冲中可用,在这种情况下,回调将几乎立即运行。或者数据将在很久以后才可用。在这种情况下,只有在数据出现后才会执行回调。这一点很重要,因为这意味着当您等待数据时,没有线程在等待任何东西。运行时处理等待并在数据出现时产生回调。
  • BeginRead是的,从您的回调中调用另一个是安全的。没有依赖关系。事实上,以这种方式进行 IO 是一种很好的方式。
  • 线程从不依赖于调用者。它们是完全独立的,只有在自然终止或进程本身终止时才会终止。
于 2012-08-25T09:27:46.170 回答
0

BeginRead通常使用称为异步 IO 的操作系统工具。Windows 内核不需要任何线程与 IO 操作相关联。

我再说一遍:您可以调用BeginRead1000 次,并且不会再启动或阻塞一个线程。

操作系统将回调的执行排队到线程池,但仅在等待结束时。EndRead然后将立即完成而无需等待。

您可以BeginRead从回调中安全地调用(通常在调用之后EndRead)。

于 2012-08-25T11:23:00.797 回答