Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 让客户端提取数据_C#_.net_Networking_Sockets - Fatal编程技术网

C# 让客户端提取数据

C# 让客户端提取数据,c#,.net,networking,sockets,C#,.net,Networking,Sockets,我正在用C#编写一个服务器,它创建一个(长的,甚至可能是无限的)IEnumerable来响应客户端请求,然后将这些结果流回到客户端 我是否可以将其设置为,如果客户端读取速度慢(或者一次可能几秒钟内根本不读取),服务器不需要一个线程暂停等待缓冲区空间清理,这样它就可以提取下两个结果s,序列化它们,并将它们填充到网络上 这是怎么回事?文档(对我来说)不清楚何时调用回调方法。它基本上是立即发生的,只是在另一个线程上,然后阻塞EndWrite等待实际写入发生吗?当套接字API中的某种低级缓冲区下溢时会发

我正在用C#编写一个服务器,它创建一个(长的,甚至可能是无限的)
IEnumerable
来响应客户端请求,然后将这些结果流回到客户端

我是否可以将其设置为,如果客户端读取速度慢(或者一次可能几秒钟内根本不读取),服务器不需要一个线程暂停等待缓冲区空间清理,这样它就可以提取下两个
结果
s,序列化它们,并将它们填充到网络上

这是怎么回事?文档(对我来说)不清楚何时调用回调方法。它基本上是立即发生的,只是在另一个线程上,然后阻塞
EndWrite
等待实际写入发生吗?当套接字API中的某种低级缓冲区下溢时会发生这种情况吗?当数据实际写入网络时是否会发生这种情况?当它被确认时会发生吗


我很困惑,所以这整个问题有可能是不正确的。如果是这样的话,你能让我转过身来,给我指出正确的方向来解决我所期望的一个相当常见的问题吗?

首先,当其他工作正在进行时,主线程可以继续执行的唯一方法是使用另一个线程。一根线不能同时做两件事

然而,我认为您试图避免的是线程对象的混乱,是的,通过使用BeginWrite这是可能的。根据你的问题

文件不清楚(对我来说) 关于何时调用回调方法 打电话来

该调用是在网络驱动程序将数据读入其缓冲区后进行的

它基本上是立即发生的吗?, 只是在另一个线程上 EndWrite上的块等待 实际写作会发生吗

不,直到它在网络驱动程序处理的缓冲区中

当某种 套接字API中的低级缓冲区 下溢

如果你所说的下溢意味着它有空间,那么是的

当数据被删除时是否会发生这种情况 实际上是写给网络的

没有

它发生在什么时候 承认

没有

编辑


就我个人而言,我会尝试使用线程。BeginWrite在幕后做了很多事情,你应该认识到。。。另外,我很奇怪,我喜欢控制我的线程。

我会更详细地回答你问题的第三部分

MSDN文件规定:

当应用程序调用BeginWrite时,系统使用单独的线程执行指定的回调方法,并在EndWrite上阻塞,直到NetworkStream发送请求的字节数或引发异常

就我的理解而言,调用BeginSend后是否立即调用回调方法取决于底层实现和平台。例如,如果IO完成端口在Windows上可用,则不会。线程池中的线程在调用它之前将被阻塞

事实上,NetworkStream的BeginWrite方法只是在我的.Net实现上调用底层套接字的BeginSend方法。Mine使用具有完成端口(如果可用)的底层WSASend Winsock函数。这比简单地为每个发送/写入操作创建自己的线程要高效得多,即使要使用线程池

如果WSASend的结果是IOPending,则Socket.BeginSend方法调用OverlappedAsyncResult.CheckAsyncCallOverlappedResult方法,后者反过来调用本机Win32函数。这将导致线程池中的一个线程阻塞,直到WSASend方法发出完成的信号,然后调用回调方法

NetworkStream.EndSend调用的Socket.EndSend方法将等待发送操作完成。它必须这样做的原因是,如果IO完成端口不可用,那么将立即调用回调方法


我必须再次强调,这些细节都是针对我的.Net和我的平台实现的,但希望这能让您有所了解。

这个问题中的一些信息并不十分准确。例如,正如我在文章中解释的,回调肯定不会总是在数据到达发送缓冲区时调用。这取决于实现,但即使在Windows上,也取决于IO完成端口是否可用。有时可能会立即调用它并在EndWrite时阻塞。我还要补充一点,为每一次发送创建一个线程是不明智的。至少,使用一个线程池。但这样做只会使事情复杂化,而且很可能比BeginWrite的效率更低。