【发布时间】:2013-04-04 12:50:26
【问题描述】:
如果来自服务器的数据不多,或者如果有很多数据并且我取消注释 Thread.Sleep(500) 行,则下面的代码有效。然而,我不想使用Thread.Sleep 行,但如果我删除它,程序将在从服务器读取所有数据之前完成。问题似乎在于EndRead() 在读取所有数据之前不会阻塞,这是可以理解的,应该通过对ReceiveCallback 的递归调用来修复,但事实并非如此。
我有一个在 Linux 上使用 C/C++ 编写的工作客户端。我正在尝试使其与 c# 和 .Net 一起使用。我在 Linux 上使用 MonoDevelop 和 .Net 4.0。感谢您就如何解决此问题提供任何帮助。
cli.send("command");
// Thread.Sleep(500);
cli.receive();
Console.WriteLine("response: {0}", cli.Response);
private Static ManualResetEvent recvEvt = new ManualResetEvent(false);
public static void receive() {
StateObject state = new StateObject();
try {
state.stream = client.GetStream();
state.stream.BeginRead(state.buffer, 0, state.bufferSize, new AsyncCallback(ReceiveCallback), state);
recvEvt.WaitOne();
recvEvt.Reset();
}
catch (ArgumentNullException ne) { errorMessage = ne.ToString(); }
catch (ArgumentException ae) { errorMessage = ae.ToString(); }
catch (ObjectDisposedException oe) { errorMessage = oe.ToString(); }
catch (InvalidOperationException ie) { errorMessage = ie.ToString(); }
catch (SocketException se) { errorMessage = se.ToString(); }
}
private static void ReceiveCallback(IAsyncResult ar) {
StateObject state = (StateObject)ar.AsyncState;
try {
int bytesRead = state.stream.EndRead(ar);
if (bytesRead > 0 ) {
state.sb.Append(Encoding.ASCII.GetString(state.buffer, 0, bytesRead));
response = state.sb.ToString();
if (state.stream.DataAvailable) {
state.stream.BeginRead(state.buffer, 0, state.bufferSize, new AsyncCallback(ReceiveCallback), state);
recvEvt.WaitOne();
recvEvt.Reset();
}else
recvEvt.Set();
}else
recvEvt.Set();
}
catch (ArgumentNullException ne) { errorMessage = ne.ToString(); }
catch (ArgumentException ae) { errorMessage = ae.ToString(); }
catch (ObjectDisposedException oe) { errorMessage = oe.ToString(); }
catch (InvalidOperationException ie) { errorMessage = ie.ToString(); }
catch (SocketException se) { errorMessage = se.ToString(); }
}
【问题讨论】:
标签: c# .net asynchronous tcpclient beginread