用COM完成耗时任务时防止崩溃(SKYPE4COM)

Jef*_*eff 2 delphi com activex skype

我正在使用Skype4COM控件.我的程序试图使用For循环从Skype中的联系人列表中删除大约3K联系人

1)这需要很多时间

2)它可能会崩溃,"MyApp已停止工作"

我的猜测是,我需要"减慢"我正在做的事情.

我会用Sleep()来做那件事吗?因为我不确定这是否会"暂停"Skype和我的程序之间的连接.

总结一下:我正在用大量的条目做一个动作,由于这个大的数量,我的程序挂了很长时间,并最终崩溃(有时).有办法防止这种情况吗?

Skype4COM顺便提一下STA.

  • 谢谢!

Ken*_*ite 6

将处理移动到单独的线程中.您的问题似乎是Windows认为应用程序已停止响应,因为它没有处理它的消息循环.

调用Application.ProcessMessages是错误的解决方案,因为它比你想象的要多得多.您最终可能会遇到重入问题或者您不期望发生的事情.

确保线程在创建COM对象之前调用CoInitialize,并在完成后调用CoUnitialize.您可以在此处找到在线程中使用COM的示例; 文章指的是ADO,但演示了使用CoInitialize/CoUninitialize.

编辑:评论后,我添加了一个在Delphi应用程序中接收自定义消息的示例.该线程需要访问UM_IDDELETED常量; 你可以通过(最好)将它添加到一个单独的单元并在主表单元和线程单元中使用该单元,或者简单地在两个单元中定义它.

// uCustomMsg.pas
const
  UM_IDDELETED = WM_APP + 100;

// Form's unit
interface

uses ..., uCustomMsg;

type
  TForm1=class(TForm)
  // ...
  private
    procedure UMIDDeleted(var Msg: TMessage); message UM_IDDELETED;
  //...
  end;

implementation

procedure TForm1.UMIDDeleted(var Msg: TMessage);
var
  DeletedID: Integer;
begin
  DeletedID := Msg.WParam;
  // Remove this item from the tree
end;

// Thread unit
implementation

uses
  uCustomMsg;

// IDListIdx is an integer index into the list or array
// of IDs you're deleting.
// 
// TheFormHandle is the main form's handle you passed in
// to the thread's constructor, along with the IDList
// array or list.

procedure TYourThread.Execute;
var
  IDToDelete: Integer;  // Your ID to delete
begin
  while not Terminated and (IDListIdx < IdList.Count) do
  begin
    IDToDelete := IDList[IDListIdx];
    // ... Do whatever to delete ID
    PostMessage(TheFormHandle, UM_IDDELETED, IDToDelete, 0);
  end;
end;
Run Code Online (Sandbox Code Playgroud)