大侠们! 考验的时候到了--------谁来解决这个依赖的矛盾问题

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:如果嫌分不够,请尽管说^-^



...全文
103 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
wy_rover 2004-10-24
  • 打赏
  • 举报
回复
大侠们,帮忙看看
http://community.csdn.net/Expert/topic/3484/3484531.xml?temp=3.069705E-02
Korny 2004-10-24
  • 打赏
  • 举报
回复
嗯,楼上的大侠们所言及是。我原来已经定义了一个消息窗体管理列表,用来标识与某聊天对象的唯一窗体,只是发送结束后,把它关闭了并从消息窗体管理列表里删除了,呵呵,其实不必关闭,下次还可能有用到,思归所讲的:)

关于“daou101”所讲的
*查看消息的方式可以象MSN messager那样啊,针对连接,而不针对消息”*
我不太明白? 在客户端里 主进程与会话进程间,传递的不是消息,而是连接?
我的架构是这样的,大体上可以分三层

1:类BaseClient: 包含以下模块
负责TCP/UDP数据接发--->消息列队--->消息事件触发器--->(虚方法)相应消息的 操作行为

2:主窗体MainWin: 继承BaseClient,重写父类相应消息的操作行为

3: 功能子窗体:被主窗体MainWin调用,根据不同消息打开相应的子窗体(比如查看好友消息、个性设置等)

所以整个系统都是以消息传递为主线,daou101(海天一鸥),能解释你的想法吗?



daou101 2004-10-24
  • 打赏
  • 举报
回复
1.对接收消息的看法:
查看消息的方式可以象MSN messager那样啊,针对连接,而不针对消息。这就象 saucer(思归)说的那样处理了。所以,在客户端主进程与会话进程间,传递的不是消息,而是连接。

happyjun2000 2004-10-24
  • 打赏
  • 举报
回复
我不知道事件处理是不是和直接this.Invoke( watcherHandler,sms); 一回事?
你可以试试事件
//委托
public delegate void DisconnectedHandler ( Client sender ) ;
//事件
public event DisconnectedHandler Disconnected ;

if ( Disconnected != null )
{
//Invokes the delegates.
Disconnected ( this ) ;
}
saucer 2004-10-24
  • 打赏
  • 举报
回复
1。好象没有别的好的方法,但为什么每次都要产生一个新的窗口呢?不能保持一个窗口变量,需要时显示,如果已经显示时,不可以添加到现有窗口?

2。在主线程能打开这窗口么?这窗口是在标记为[STAThread]的主线程上生成的么?

http://support.microsoft.com/?id=841295
hglai 2004-10-24
  • 打赏
  • 举报
回复
占个一楼,顶\

111,119

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧