首页 新闻 论坛 群组 Blog 文档 下载 读书 Tag 网摘 搜索 .NET Java 游戏 视频 人才 外包 培训 数据库 书店 程序员
中国软件网
欢迎您:游客 | 登录 注册 帮助
  • [向jameshooo提问]关于跨线程使用ActiveX控件的问题 [已结帖,结帖人:hailongxl]
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hailongxl
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 结帖率:
    发表于:2008-11-18 09:45:21 楼主
    PS:本文中所有线程均使用CoInitialize(NULL)进行COM初始化。

    跨套间如何使用ActiveX控件?

    COM跨套间使用时需要列集和散集(书上都是这么说的),但是不知道如何操作。

    比如像使用ADO访问数据库(通过import导入msado15.dll,形成了IConnectionPtr智能指针)。
    在主线程中定义了一个IConnectionPtr的变量m_conn,访问属性设为public,并CreateInstance然后连接数据库。
    然后创建工作线程,在工作线程中直接通过((CMain*)AfxGetMainWnd())->m_conn来使用此数据库连接(使用了很长时间),没有出现过错误,为何?

    更棘手的问题:
    在基于对话框的应用程序的主对话框(肯定是主线程喽)上通过右键菜单中的“插入ActiveX控件”,插入了一个ActiveX控件在主对话框上。然后通过类向导为该ActiveX控件关联到一个成员变量,例如将一个MSComm控件关联到m_comm。
    然后创建工作线程,将主对话框的指针当作线程参数传递到工作线程,在工作线程中直接通过此参数来访问其m_comm变量来使用MSComm控件,也是正常的。
    这种方法有问题吗?如果有问题的话,正确的方法应该怎么操作?
    100  修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • unsigned
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 5

      2

      6

    发表于:2008-11-18 10:12:331楼 得分:10
    使用CoInitializeEx(NULL,COINIT_MULTITHREADED)代替CoInitialize(NULL)
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Amuro1987218
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 10:27:242楼 得分:10
    用GIT吧,搜索一下,用着方便
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • wang921718
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 10:39:123楼 得分:0
    该回复于2008-11-22 13:13:23被版主删除
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hailongxl
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 12:04:044楼 得分:0
    引用 1 楼 unsigned 的回复:
    使用CoInitializeEx(NULL,COINIT_MULTITHREADED)代替CoInitialize(NULL)

    这样肯定是不安全的,控件都是Apartment的。

    引用 2 楼 Amuro1987218 的回复:
    用GIT吧,搜索一下,用着方便

    问题是要在线程中使用该控件的所有功能,我该把哪个接口放到GIT中去呢?接口的IID呢?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jameshooo
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

      5

    发表于:2008-11-18 12:11:205楼 得分:0
    是否能不用列集而跨线程传递指针,取决于组件的设计,对于组件被设计成free或者both类型的,说明组件内部实现了同步控制,这样的组件可以直接跨线程调用而不会造成冲突,检查一下注册表中组件登记的套间类型。
    对于只支持apartment的组件,它内部并未进行同步控制,直接跨线程调用会产生不可预知的后果,尤其是组件方法中需要传递其他接口指针时几乎百分百出错。
    如果一个组件支持free或both,那么它的方法里需要传递的其他组件也必须实现成free或both类型,否则就失去了free的意义。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hailongxl
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 12:50:396楼 得分:0
    to jameshooo:
    您说的这些我倒是明白。

    我不明白的地方:
    类似于MSCOMM控件,既然是一个ActiveX控件,那么它一定是Apartment的,不可能是Free或者Both。

    我是使用IDE的右键菜单中的“插入ActiveX控件...”将MSCOMM插入到主对话框(程序基于对话框,MFC)上的。
    然后我需要在工作线程中使用此控件,应该怎么办?
    1、通过CoMarshalInterThreadInterfaceIntoStream和CoGetInterfaceAndReleasStream?如果可行的话,是否工作线程对MSCOMM控件调用的所有方法实际上都是在主线程中执行的?如果MSCOMM有一个方法是一个长时间的操作,那是不是会引起主线程界面无响应?
    2、直接在工作线程中创建MSCOMM控件的实例。对于MFC程序,是否需要在每一个工作线程中调用AfxEnableControlContainer函数?还是只需要在APP类中调用此函数?还是有其它的解决方法?
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • Amuro1987218
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 12:54:357楼 得分:30
    列集的话就尽量找一个可导航到最多接口的接口指针,最终调用应该还是主线程执行的,如果该调用的堵塞部分也在主线程,应该会使得主线程界面无相应
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hailongxl
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-18 14:17:538楼 得分:0
    谢谢楼上的热心回复。

    我是使用IDE的右键菜单中的“插入ActiveX控件...”将MSCOMM插入到主对话框(程序基于对话框,MFC)上的。
    然后我需要在工作线程中使用此控件,应该怎么办?
    1、通过CoMarshalInterThreadInterfaceIntoStream和CoGetInterfaceAndReleasStream?如果可行的话,是否工作线程对MSCOMM控件调用的所有方法实际上都是在主线程中执行的?如果MSCOMM有一个方法是一个长时间的操作,那是不是会引起主线程界面无响应?
    2、直接在工作线程中创建MSCOMM控件的实例。对于MFC程序,是否需要在每一个工作线程中调用AfxEnableControlContainer函数?还是只需要在APP类中调用此函数?还是有其它的解决方法?

    期待对第一个问题的更肯定的答复以及第二个问题的回答。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • jameshooo
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    • 2

      5

    发表于:2008-11-19 00:31:159楼 得分:50
    1、理解完全正确。
    2、一个组件如果设计得好,每个方法调用都不会占用很长时间,如果真的有耗时操作,应该在组件内部实现多线程,然后使用连接点的方式通知客户端操作状态和结果。
    另外,不要被ActiveX这个词给迷惑了,老实说MFC中用ActiveX这个词就不对,_ConnectionPtr和mscomm组件都是普通的组件,即创建即用,真正的ActiveX组件是必须存活在容器中的。
    修改 删除 举报 引用 回复
    进入用户个人空间
    加为好友
    发送私信
    在线聊天
    • hailongxl
    • 等级:
    • 可用分等级:
    • 总技术分:
    • 总技术分排名:
    发表于:2008-11-19 08:30:4210楼 得分:0
    谢谢,明白了。
    修改 删除 举报 引用 回复

    网站简介广告服务网站地图帮助联系方式诚聘英才English 问题报告
    北京创新乐知广告有限公司 版权所有 京 ICP 证 070598 号
    世纪乐知(北京)网络技术有限公司 提供技术支持
    Copyright © 2000-2008, CSDN.NET, All Rights Reserved