ManualResetEvent 允许线程通过发信号互相通信。通常,此通信涉及一个线程在其他线程进行之前必须完成的任务。当线程开始一个活动(此活动必须在其他线程进行之前完成)时,它调用 Reset 将 ManualResetEvent 设置为非终止状态。此线程可被视为控制 ManualResetEvent。调用 ManualResetEvent 上的 WaitOne 的线程将阻塞,并等待信号。当控制线程完成活动时,它调用 Set 以发出等待线程可以继续进行的信号。并释放所有等待线程。
调试欢乐多
private static ManualResetEvent connectDone = new ManualResetEvent(false);
private static ManualResetEvent sendDone = new ManualResetEvent(false);
private static ManualResetEvent receiveDone = new ManualResetEvent(false);public void StartClient()
{
IPAddress ipAddress = IPAddress.Parse(strIPAddress);
IPEndPoint remoteEP = new IPEndPoint(ipAddress,vodPort);
Socket client = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);client.BeginConnect(remoteEP,new AsyncCallback(ConnectCallBack),client);
connectDone.WaitOne();Send(client,((VodMsg)SendMsg[0]).ToString());
SendMsg.Remove(SendMsg[0]);
sendDone.WaitOne();Receive(client);
receiveDone.WaitOne();client.Shutdown(SocketShutdown.Both);
client.Close();
}然后在Connect、Send、Receive、的回调函数里分别设置状态为.Set(),以便线程继续运行。
这样,Send以前可以保证连接已经建立,Receive前可以保证消息已经发送,关闭前可以保证消息已经接收。不会出现运行Receive的回调函数的时候Socket已经关闭了。-------------
只是我自己的想法,不对的地方大家多多指教!
public delegate void VoidFunc();
public delegate void BoolFunc(bool b);
public delegate void StrnFunc(string s);
public delegate void ByteFunc(byte[] b);/// <summary>
/// This structure contains one delegate method for each override event
/// method in the serial port base class. Each delegate provides a hook
/// that can be used by any application that wishes to connect to the
/// asynchronous OnXXX methods.
/// </summary>
public struct WithEvents
{
public VoidFunc Break;
public VoidFunc TxDone;
public StrnFunc Error;
public ByteFunc RxChar;
public BoolFunc CtsSig;
public BoolFunc DsrSig;
public BoolFunc RlsdSig;
public BoolFunc RingSig;
}...
public class SerialPort
{
private WithEvents ev;
private ManualResetEvent recvrEvent;//接收数据线程启动的信号
private ManualResetEvent writeEvent;
private Thread rxThread; //接收数据的线程
public SerialPort(WithEvents ev)
{
this.ev = ev;
}
//打开串口
protected bool Open(...) //就是我前面调用的this.Port.Open
{
...
this.recvrEvent = new ManualResetEvent(false);
...
//启动线程
this.rxThread = new Thread(new ThreadStart(ReceiveThread));
this.rxThread.Priority = ThreadPriority.AboveNormal;
this.rxThread.Start();
// Wait for receive thread to start.
this.recvrEvent.WaitOne(500, false);
//成功打开了串口
}
private void ReceiveThread()
{
//接收数据
//触发事件
...
this.OnRxChar(buf);
}
}