C# 异步套接字+;waitone()
让我们从一些代码开始:C# 异步套接字+;waitone(),c#,sockets,asynchronous,C#,Sockets,Asynchronous,让我们从一些代码开始: class InternetConnector { private struct ConnectionData { public Action<Socket> SuccessHandler { get; set; } public ClientStateObject clientObj { get; set; } public Action<Exception> ErrorHandle
class InternetConnector
{
private struct ConnectionData
{
public Action<Socket> SuccessHandler { get; set; }
public ClientStateObject clientObj { get; set; }
public Action<Exception> ErrorHandler { get; set; }
public Socket Socket { get; set; }
}
public static ManualResetEvent processingDone = new ManualResetEvent( false );
public static ConcurrentQueue<string> messages = new ConcurrentQueue<string>();
public bool ReceiveMessage(Action<Socket> successHandler, Action<Exception> errorHandler)
{
ClientStateObject obj = new ClientStateObject();
obj.server = client;
var connectionData = new ConnectionData
{
ErrorHandler = errorHandler,
SuccessHandler = successHandler,
Socket = client,
clientObj = obj
};
if (Connected)
{
client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
receive = true;
receiveDone.WaitOne();
}
return receive;
}
private static void ReceiveCallback(IAsyncResult ar)
{
ConnectionData connectionData = new ConnectionData();
bool complete = false;
try
{
connectionData = (ConnectionData)ar.AsyncState;
Socket client = connectionData.Socket;
int num = client.EndReceive(ar);
{
connectionData.clientObj.stringBuffer.Append(Encoding.ASCII.GetString(connectionData.clientObj.buffer, 0, num));
string response = connectionData.clientObj.stringBuffer.ToString();
string[] msgs = response.Split('&');
for (int i = 0; i < msgs.Count(); i++)
{
string sts = msgs[i];
messages.Enqueue(sts + "&" );
}
receiveDone.Set();
if (connectionData.SuccessHandler != null)
{
connectionData.SuccessHandler(client);
processingDone.WaitOne();
client.BeginReceive(connectionData.clientObj.buffer, 0, ClientStateObject.bufSize, 0, new AsyncCallback(ReceiveCallback), connectionData);
}
}
}
catch (Exception e)
{
if (connectionData.ErrorHandler != null)
connectionData.ErrorHandler(e);
}
}
public partial class Form1 : Form
{
private InternetConnector client = new InternetConnector();
private bool isRunning = false;
private void AsyncSuccessHandler(Socket socket)
{
if (InvokeRequired)
{
BeginInvoke(new Action( () => AsyncSuccessHandler( socket ) ));
return;
}
if (InternetConnector.messages.Count() == 0)
{
status.Text = "Signals Receiver: Connected";
status.ForeColor = Color.Green;
isRunning = true;
client.ReceiveMessage(AsyncSuccessHandler, AsyncErrorHandler);
}
else
{
GUIChangeOnConnection();
InternetConnector.processingDone.Set();
}
}
private void GUIChangeOnConnection()
{
for( int i = 0; i < InternetConnector.messages.Count; i++ )
{
string message;
InternetConnector.messages.TryDequeue( out message );
// process the message
}
}
}
class互联网连接器
{
私有结构连接数据
{
公共操作成功处理程序{get;set;}
公共ClientStateObject clientObj{get;set;}
公共操作错误处理程序{get;set;}
公共套接字{get;set;}
}
public static ManualResetEvent processingDone=新的ManualResetEvent(false);
公共静态ConcurrentQueue消息=新建ConcurrentQueue();
public bool ReceiveMessage(操作成功处理程序、操作错误处理程序)
{
ClientStateObject obj=新ClientStateObject();
obj.server=客户端;
var connectionData=新的connectionData
{
ErrorHandler=ErrorHandler,
SuccessHandler=SuccessHandler,
套接字=客户端,
clientObj=obj
};
如果(已连接)
{
client.BeginReceive(connectionData.clientObj.buffer,0,ClientStateObject.bufSize,0,新异步回调(ReceiveCallback),connectionData);
接收=真;
receiveDone.WaitOne();
}
回执;
}
私有静态void ReceiveCallback(IAsyncResult ar)
{
ConnectionData ConnectionData=新的ConnectionData();
bool complete=false;
尝试
{
connectionData=(connectionData)ar.AsyncState;
socketclient=connectionData.Socket;
int num=client.EndReceive(ar);
{
Append(Encoding.ASCII.GetString(connectionData.clientObj.buffer,0,num));
string response=connectionData.clientObj.stringBuffer.ToString();
字符串[]msgs=response.Split('&');
对于(int i=0;iAsyncSuccessHandler(套接字));
返回;
}
if(InternetConnector.messages.Count()==0)
{
status.Text=“信号接收器:已连接”;
status.ForeColor=Color.Green;
isRunning=true;
ReceiveMessage(AsyncSuccessHandler,AsyncErrorHandler);
}
其他的
{
guichangeoconnection();
InternetConnector.processingDone.Set();
}
}
私有void guichangeoconnection()
{
对于(int i=0;i
现在问题来了
一切正常。正在从套接字读取。但是调用processingDone.WaitOne();
将无限期地阻止回调,直到调用processingDone.Set();
返回得太早
我通过在guichangeoconnection();
-函数结束括号行的末尾设置断点来验证它。它命中断点并查看InternetConnector。消息
我看到队列不是空的,这意味着for循环没有完成。
第二次命中此断点时,队列中的消息数量急剧增加
我做错了什么?或者我的设计不正确
谢谢。我看到的第一件事是,您不必执行
ConnectionData ConnectionData=new ConnectionData()
,因为您是在try子句中分配它的。因此您可以安全地删除=new ConnectionData()
您能提供更多的客户端代码吗?AsyncSuccessHandler
方法是第一次被Socket.BeginConnect调用的吗?为什么要执行异步接收,因为在回调完成之前您一直在阻塞,使整个操作同步?@默认情况下,我不会得到编译器错误:“使用未初始化变量”?@Serge,是的,它是从BeginConnect()调用的。为什么?