先放两段代码: private void beginReadStatus()
{
receiveDataBuffer = null;
receiveDataBuffer = new Byte[this.tcpclient.ReceiveBufferSize];
tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
}
private void doReadStatus(IAsyncResult ar)
{
Stream stream = (Stream)ar.AsyncState;
if (stream.CanRead)
{
int dataSize = tcpstream.EndRead(ar);
……(业务代码)
tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
}
}这是个异步读的过程,在doReadStatus中stream.CanRead=true,但int dataSize = tcpstream.EndRead(ar)后dataSize=0,执行完业务代码后,再beginread,然后就又重复这个过程了,无限循环,导致cpu占用率很高。
不明白的是流(tcpstream)里数据大小为0,为什么还可以读?请真正明白的人帮忙解答下~
{
receiveDataBuffer = null;
receiveDataBuffer = new Byte[this.tcpclient.ReceiveBufferSize];
tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
}
private void doReadStatus(IAsyncResult ar)
{
Stream stream = (Stream)ar.AsyncState;
if (stream.CanRead)
{
int dataSize = tcpstream.EndRead(ar);
……(业务代码)
tcpstream.BeginRead(receiveDataBuffer, 0, receiveDataBuffer.Length, new AsyncCallback(doReadStatus), tcpstream);
}
}这是个异步读的过程,在doReadStatus中stream.CanRead=true,但int dataSize = tcpstream.EndRead(ar)后dataSize=0,执行完业务代码后,再beginread,然后就又重复这个过程了,无限循环,导致cpu占用率很高。
不明白的是流(tcpstream)里数据大小为0,为什么还可以读?请真正明白的人帮忙解答下~
就是有一点不明白,为什么会一直循环,流里分明没有数据。beginread不是会在流里有数据时才触发它的回调函数吗?
就是有一点不明白,为什么会一直循环,流里分明没有数据。beginread不是会在流里有数据时才触发它的回调函数吗?canread在流断了就会为false。现在问题是为什么流里没东西还会一直在执行doReadStatus这个方法?不是只有当异步请求来时才会异步读取吗?打个比方说, 你会看的懂书吧,可不代表你现在在看读书啊!明白?
就是有一点不明白,为什么会一直循环,流里分明没有数据。beginread不是会在流里有数据时才触发它的回调函数吗?你怎么知道流里没有数据?你别管其它,看看receiveDataBuffer 这个数组里是否有数据了。
就是有一点不明白,为什么会一直循环,流里分明没有数据。beginread不是会在流里有数据时才触发它的回调函数吗?canread在流断了就会为false。现在问题是为什么流里没东西还会一直在执行doReadStatus这个方法?不是只有当异步请求来时才会异步读取吗?打个比方说, 你会看的懂书吧,可不代表你现在在看读书啊!明白?
就是有一点不明白,为什么会一直循环,流里分明没有数据。beginread不是会在流里有数据时才触发它的回调函数吗?你怎么知道流里没有数据?你别管其它,看看receiveDataBuffer 这个数组里是否有数据了。
int dataSize = tcpstream.EndRead(ar)这句后,dataSize=0,然后执行业务代码,最后再beginRead,就立马又到doReadStatus这个回调函数里面了,而且endread后dataSize还是0,一直在循环,不解。。
他有病,自己不懂装懂,还嘲笑别人。你要再不信,只能看官方说明了,本来我是懒得去找,没想到固执的人就是顽固不化。
http://msdn.microsoft.com/ZH-CN/library/vstudio/system.net.sockets.networkstream.read(v=vs.110).aspx
备注
该方法将数据读入 buffer 参数并返回成功读取的字节数。 如果没有可读取的数据,则 Read 方法返回 0。 Read 操作将读取尽可能多的可用数据,直到达到 size 参数指定的字节数为止。 如果远程主机关闭了连接并且已接收到所有可用数据,Read 方法将立即完成并返回零字节。
流断了当然会返回false了,流里无数据和流断了是两个概念啊.你需要判断的是流里有无数据,若有则读取
他有病,自己不懂装懂,还嘲笑别人。你要再不信,只能看官方说明了,本来我是懒得去找,没想到固执的人就是顽固不化。
http://msdn.microsoft.com/ZH-CN/library/vstudio/system.net.sockets.networkstream.read(v=vs.110).aspx
备注
该方法将数据读入 buffer 参数并返回成功读取的字节数。 如果没有可读取的数据,则 Read 方法返回 0。 Read 操作将读取尽可能多的可用数据,直到达到 size 参数指定的字节数为止。 如果远程主机关闭了连接并且已接收到所有可用数据,Read 方法将立即完成并返回零字节。其实我很少骂人的,但我真的很想骂你SB。
我嘲笑你了吗? SB,
我笑我自己忘记了。 再送你两字SB
最后说明下,对于网络流,CanRead属性在建立连接后永远为true,所以那个是无需判断的。对于普通流,例如内存流,判断是否读取结束就是判断返回的字节数是否为0,对于读取到末尾的内存流,你再读取也不会报错,只是总是返回给你0字节。因此微软将Socket流化处理时也采用了该原理,判断网络是否断开就用返回的字节数是否为0来表示,如果TCP连接还保持着,Read或BeginRead方法就会一直等待下面可能进来的数据,不会将0字节返回给用户。返回0字节就意味着肯定不会再有数据进来了,那就是TCP连接断开了。