您现在的位置:首页 >> API >> API >> 内容

DCOM当中保证异步作业不因远端COM客户断开而中止的解决方案(Delphi)

时间:2011-9-3 15:45:16 点击:

  核心提示:问题起源:最近开发了一个DCOM服务器,内部有个队列任务。客户端可以连接调用以添加任务到队列。现在有个问题是当客户端调用完断开连接后,DCOM服务器的队列任务还没执行完毕DCOM就退出了。请问有什么办...

问题起源:最近开发了一个DCOM服务器,内部有个队列任务。客户端可以连接调用以添加任务到队列。现在有个问题是当客户端调用完断开连接后,DCOM服务器的队列任务还没执行完毕DCOM就退出了。请问有什么办法可以让队列执行完才退出呢?

简单的解决方案演示:演示是通过增加一个方法Method1,被用户调用后,记下自己当前的ThreadID(GetCurrentThradId获得),然后调用_Addref增加引用计数。
启动一个线程,在线程当中只做一个事,等待15秒,线程置为FreeOnTerminate,并且OnTerminated事件置过程放在COM对象当中,事件发生时(线程是主线程),调用_Release释放引用计数。此时COM的处理线程会在等待消息,所以不会去释放对象,但是此时可以PostThreadMessage(ThreadID,0,0)唤醒线程,线程就会检查计数,(而此时计数正好为0)并释放对象。

unit Unit4;

{$WARN SYMBOL_PLATFORM OFF}

interface

uses
  Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
  DBClient, Project2_TLB, StdVcl;

type
  Tcc = class(TRemoteDataModule, Icc)
  private
    { Private declarations }
    ThrdID: DWORD;
    procedure OnThradTerminated(Sender: TObject);
  protected
    class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
    procedure Method1; safecall;
  public
    { Public declarations }
  end;

  //一个定时器线程
  TMyThread = Class(TThread)
    protected
      procedure Execute;override;
  End;
implementation

{$R *.DFM}

procedure TMyThread.Execute;
var
  I: Integer;
begin
  I := 15000;//15秒
  while I>0 do begin
    Sleep(15);
    Dec(I,15);
  end;

end;
class procedure Tcc.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
begin
  if Register then
  begin
    inherited UpdateRegistry(Register, ClassID, ProgID);
    EnableSocketTransport(ClassID);
    EnableWebTransport(ClassID);
  end else
  begin
    DisableSocketTransport(ClassID);
    DisableWebTransport(ClassID);
    inherited UpdateRegistry(Register, ClassID, ProgID);
  end;
end;

procedure Tcc.Method1;
var
  Thd: TMyThread;
begin
  //添加引用计数
  _AddRef;
  //取得当前线程的ID,以方便释放时唤醒
  ThrdID := GetCurrentThreadId;
  //创建一个线程用于15秒后释放计数,以模拟线程异步操作
  Thd := TMyThread.Create(True);
  //置线程线程事件过程,以执行释放计数的过程代码
  Thd.OnTerminate := OnThradTerminated;
  //线程自动销毁
  Thd.FreeOnTerminate := True;
  //唤醒线程
  Thd.Resume;
end;

procedure Tcc.OnThradTerminated(Sender: TObject);
begin
  //线程结束,表示异步任务完成,释放计数
  _Release;
  //唤醒COM线程
  PostThreadMessage(ThrdID,0,0,0);
end;

initialization
  TComponentFactory.Create(ComServer, Tcc,
    Class_cc, ciMultiInstance, tmApartment);
end.

作者:unsigned 来源:转载
共有评论 0相关评论
发表我的评论
  • 大名:
  • 内容:
本类推荐
  • 没有
本类固顶
  • 没有
  • 盒子文章(www.2ccc.com) © 2017 版权所有 All Rights Reserved.
  • 沪ICP备05001939号