关于服务器端COM对象如何使用多线程的方式调用另一个COM对象的服务?请诸位帮忙!特别邀请menxin、xeen、coolzew、Sachow等大侠请来指点。(

  • 主题发起人 主题发起人 siyan
  • 开始时间 开始时间
S

siyan

Unregistered / Unconfirmed
GUEST, unregistred user!
关于服务器端COM对象如何使用多线程的方式调用另一个COM对象的服务?请诸位帮忙!特别邀请menxin、xeen、coolzew、Sachow等大侠请来指点。(200分)<br />原贴请见http://www.delphibbs.com/delphibbs/dispq.asp?lid=1940274
既然大家都对我往主线程PostMessage的方式调用另外的COM对象处理业务持不支持意见
那我就把问题单独拿出来,其实业务很简单,客户端录入一笔记录时,当前数据对象
处理这边记录的保存操作,保存完毕之后,需要调用另外的COM对象的服务对这边记录
与其他表的某些记录进行对比操作,为不影响客户端继续录入,所以需要调用时以多线程的
方式调用。如何处理请诸位指点!不胜感激!
 
不懂。。。帮你提前
 
为什么要在主窗体处理,可以一个RDM调用另外一个RDM,RDM们尽量不要与主窗体相关
 
创建多个子线程,在子线程中处理就可以了
 
你這樣處理﹐忽視了事務在數據庫處理中重要性﹐即然是要一起處理的﹐我想是
不能先保存好記錄﹐ 再調用另一個COM來做其它的處理﹐(關聯表了﹐扣減庫存了)﹐
試問SAVE成功﹐但在另一個線程中COM對象中出現異常如何處理。況且這樣寫的程序在
可讀性﹐可維護性上都是不盡人意的。
我想你可不可以先讓USER將所有數據錄入完﹐再一次處理呢﹖我想這樣更合理些吧﹗
像SQL SERVER是面對數據集的﹐這樣的處理效率會好很多。多線程在處理多時復雜的運算
是很好的﹐但要在其中處理數據庫我想不是很安全﹐況且對DELPHI 5 以上的版本對VCL線程
安全的機制不是很了解﹐只是按李維的分析呢是夠安全的。我覺得用多線程做QUERY還可以
但我不會在其中做業務處理。
胡言亂語﹐別見笑﹗ good luck! ^_^
 
保存完毕之后,需要调用另外的COM对象的服务对这边记录
-------------------------------------------------------
与其他表的某些记录进行对比操作
-----------------------------------------------
对比的目的是什么,如果是判断输入合法性,那就不能采用线程了,这种情况
需要同步调用。
最重要的是:你的这个对比操作和数据保存是否成功有无关系(或者说是否应该
在一个事务 Context里)?
如果是这种情况,最好把事务构造在存储过程里,这样是最可靠的.
 
后续的对比操作与记录保存没有任何关系,只有记录保存成功了,就可以进行对比
而对比是否异常与其他的没有关系,因为这个对比的过程比较耗时,如果把保存和对比放在
同一事务里,则客户端需要等待近10秒钟,我想这个是无法接受的,所以需要启用多线程
而在COM服务器里该如何处理多线程还没有接触过,所以请教大家,是否是需要自己建立
线程类,在线程类里创建COM对象,然后调用对象的方法(这样会否和COM的线程模型冲突),
还是有什么其他的方法,请指教
 
1.如果你一定要使用线程要注意:
在线程中使用Com对象主要要注意线程模式问题;
所有使用Com对象的线程都要进行Com初始化;
在不同Apartment中传递接口要进行必要的Marshall;
在线程中对一些全局对象进行读写的时候要进行必要的同步;
2.看看你的功能能不能放在触发器中实现,这样能避免线程减少程序的复杂性.
 
to xeen
在触发器里做应该也行吧,只是这个对比的逻辑较复杂,我在程序里都有两百多行的代码
放在触发器里不知道好不好实现,如果在服务器端实在不好处理,我就试一下
另外:触发器好像也会影响数据写入的效率吧,如果是就不可行了
如果我一定要使用多线程,那要怎么做呢,能不能把详细的说明一下,万事开头难啊
 
不太清楚你具体的实现,前面你说了在要对全局的队列增加数据。
不知道作了同步保护没有,否则你在不同线程里写同一个对象有可能出问题.
 
这个不是问题,加上临界区就可以了吧
我想问的是,如果我在一个COM对象里需要使用多线程方式调用另一个COM对象的方法(
对象已经创建),我该如何开始呢,大概的步骤有哪些呢?(至于要注意的地方你已经说了)
 
如果你的这两个线程在不同的Apartment中(使用STA模式的Com服务器一个
线程一个Apartment,所以两个线程肯定在不同的Apartment中),你必须
对接口进行Marshall。或者使用全局接口表。可以参考这篇:
http://www.delphibbs.com/delphibbs/dispq.asp?lid=254393
 
呵呵,我也来说两句了,不知道是不是对题。
既然你已经做了com+组件,那么你在你的其中一个你需要调用其他com+接口中写函数或过程。
这样可以实现你的此com+调用彼com+的目的。
如果有不对的,我闪~
 
to xeen
那好像不是我要的答案,Marshall接口之后调用接口的方法,还是得等调用得过程执行完毕
才能返回,达不到多线程的效果,我希望能够不用等待直接返回。
不过看了那篇文章之后有点疑惑,我在一个COM对象里创建另一个COM对象然后调用他的一个
方法,是否也需要使用CoInitialize,就像
procedure TSvr1.GetDataFromSvr2(const XM: WideString;
var DATA: OleVariant);
var
appsvr2:ISvr2;
begin
CoInitialize;
appsvr2:=CreateCOMObject(CLASS_SVR2) as ISvr2;
appsvr2.GetData(xm);
CoUnInitializeEx;
end;
而如果没有这两句,会怎么样呢
 
to 阿西喊佛
问题就在于这个调用的过程这么写,才能达到多线程的效果,请指教
 
我在一个COM对象里创建另一个COM对象然后调用他的一个
方法,是否也需要使用CoInitialize.
-----------------------------------------------------
应该是不需要的,系统在创建Com对象的时候已经根据注册表里的的值
进入相应的线程模式了,而已用CreateCOMObject、CreateOleObject
得到的接口是已经Marshall好的了.
那好像不是我要的答案,Marshall接口之后调用接口的方法,还是得等调用得过程执行完毕
--------------------------------------------------------------------------------
如果你的Com服务器上的线程是STA,那你无论如何都得排队,因为它一次只允许一个线程
进入Apartment访问Com对象.
我想到的办法是在创建一个新的线程来作你的对比操作,你其它的 TApartmentThread
向这个线程发消息,或者设置一个信号量来通知它处理数据.
 
to xeen
能否举一个简单的例子说明一下具体的步骤呢,这两天被问题搞得头晕
 
大概是下面的代码,hMutex是一个互斥员内核对象的句柄
在你Apartmentthread 中:
if 保存数据成功 then
begin

if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
队列成员入列;
ReleaseMutex(hMutex);
end;
在你的处理数据线程:
while bContinuedo
begin
if WaitForSingleObject(hMutex,INFINITE) = WAIT_OBJECT_0 then
if 队列非空 then

队列成员出列;
ReleaseMutex(hMutex);
if 已取得一个成员 then
处理数据;
end;
 
to xeen
你的意思是否是说我的比对对象一创建就执行 while bContinuedo
一直到对象销毁(或其他方法终止)
不管有没有数据比对,这样会不会占有大量的时间片导致影响其他服务的执行呢
 
不是对象创立,是程序一执行就创建一个服务线程.你的服务器是Exe型的吧,如果是
Dll型的就麻烦了.WaitForSingleObject 函数在不返回的时候不会占用Cpu时间片.
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
后退
顶部