大侠们! 考验的时候到了--------谁来解决这个依赖的矛盾问题
Korny 2004-10-24 10:56:41 讨论的环境是一个消息系统。
客户端与服务器采用异步socket收发消息,当客户端收到服务端的消息时,用一个消息窗体打开来阅读,如果直接用show()方法打开时,会使消息阅读窗体无响应,用showdialog()则可以,很显然我们必须用show()方法打开,于是我用一个delegate来打开此消息阅读窗体,此方法可以实现。但是为什么收到消息(此消息由socket.beginreceive异步接收,然后进入列队)用show()方法不能直接显示?
我是用如下方法解决的,虽然可行但是否存在隐患(个人感觉主窗体的.invoke被经常调用是否有影响)
// SerialMessage 是自己的类
//定义
public delegate void WatcherTreeEventHandler(SerialMessage sm);
///////////////////////////////////////////////////////////////////////////
//假设有消息收到
object [] sms=new object[1];
sms[0]=sm;
WatcherTreeEventHandler watcherHandler = new WatcherTreeEventHandler( OperWinViewSM);
this.Invoke( watcherHandler,sms);
////////////////////////////////////////////////////////////////////////
//用阅读窗体打开
private void OperWinViewSM(SerialMessage sm)
{
//para 1 :receive
fss=new FrmSendSM(this);
fss.Flag_SR=1;
fss.SMSourceLoginName=sm.LoginName;
fss.sm=sm;
fss.txtSendList.Text=" 接收人:"+sm.LoginName+";";
frmAL.Add(frmmw);
fss.Show();
}
//////////////////////////////////////////////////////////////////////
以什么方法可以再优化吗?
第二,假设收到一条p2p消息,同理我们用 this.Invoke( watcherHandler,sms)要调用一个打开p2p传输的窗体,此p2p窗体包含一个activex控件,但打开窗体时会出现System.Threading.ThreadStateException: 因为当前线程不在单线程单元中,故无法实例化 ActiveX 控件“b09de715-87c1-11d1-8be3-0000f8754da1”的出错,估计是this.Invoke( watcherHandler,sms)的原因。如果不用异步则连窗体也打不开,如果用异步则出错“当前线程不在单线程单元中”,按理说在MAIN前设置[STAThread] 或指设置Thread.CurrentThread.ApartmentState = ApartmentState.STA;可以解决activex出错的问题,但实际还是出错了。
希望各位给小弟拨开困惑已久的云雾,或是谈谈您更好的构架
ps:如果嫌分不够,请尽管说^-^