C# 异步回调&;插座

C# 异步回调&;插座,c#,sockets,asynccallback,C#,Sockets,Asynccallback,嗨,我想知道更多关于异步回调如何与套接字一起工作的信息 假设从我的UI线程调用BeginRead方法,并传入名为Read的回调。根据我的理解,BeginRead生成一个新线程(线程a),因此UI线程中的代码执行仍然可以继续。回调读取在线程A中执行,对吗?它在结束读取时阻塞 那么,一旦回调结束,线程A是否会自动关闭自身 假设调用回调后,线程A会自动关闭: 这是否意味着在线程结束之前将另一个开始线程称为线程A是安全的?此起始将产生线程B。线程B是否会执行失败或正确放置,是否会因为调用线程A已结束而在

嗨,我想知道更多关于异步回调如何与套接字一起工作的信息

假设从我的UI线程调用BeginRead方法,并传入名为Read的回调。根据我的理解,BeginRead生成一个新线程(线程a),因此UI线程中的代码执行仍然可以继续。回调读取线程A中执行,对吗?它在结束读取时阻塞

那么,一旦回调结束,线程A是否会自动关闭自身

假设调用回调后,线程A会自动关闭:


这是否意味着在线程结束之前将另一个开始线程称为线程A是安全的?此起始将产生线程B线程B是否会执行失败或正确放置,是否会因为调用线程A已结束而在某个点终止?或者线程根本不依赖于调用方吗?

这里有一些误解。调用
BeginRead
时,将从应用程序的内部线程池中调用指定的回调。通常不会启动新线程,尽管可能会启动一个——这是由.NET的内部调度程序启动的

如果在调试器中中断程序并转到“线程”视图,则应该会看到一组名为工作线程的线程。通常他们都在睡觉,等待工作。这是一种比
BeginRead
在每次您想阅读时启动线程快得多的方法。取而代之的是,这些工作人员躺在后台,随时准备出发

回调完成后,工作线程返回池,准备执行更多操作

至于你剩下的问题:

  • 回调不应在
    EndRead
    中阻塞。您的应用程序中不会出现阻塞。IO数据将被缓冲,在这种情况下,回调几乎会立即运行。否则,数据将很晚才能得到。在这种情况下,回调将仅在数据出现后执行。这一点很重要,因为这意味着在等待数据时,没有线程在等待任何东西。运行时以等待为例,并在数据出现时生成回调
  • 是的,从回调调用另一个
    BeginRead
    是安全的。没有依赖关系。事实上,这样做是一个很好的方法
  • 线程从不依赖于调用方。它们是完全独立的,只有在自然终止或进程本身消亡时才会消亡

BeginRead
通常使用一种称为异步IO的操作系统功能。Windows内核不要求任何线程与IO操作相关联

我重复一遍:您可以调用
BeginRead
1000次,没有一个线程会启动或被阻塞

操作系统将回调的执行排队到线程池中,但仅当等待结束时<代码>结束读取将立即完成,无需等待


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

否!BeginRead根本不需要任何线程。就我所知,Socket和NetworkStream类的非阻塞方法使用I/O完成端口。就像@usr所说的,BeginRead不应该使用线程池线程。我没有说BeginRead启动线程,只是说如果需要回调,回调将在线程池中的线程上运行。IO运行时没有线程