delphi - 使用 COM (SKYPE4COM) 执行耗时任务时防止崩溃

标签 delphi com activex skype

我正在使用Skype4COM控件。但是,我的程序尝试使用 For 循环从 Skype 的联系人列表中删除大约 3K 个联系人

1)需要很多时间

2) 它可能会崩溃,并显示“MyApp 已停止工作”

我的猜测是,我需要以某种方式“放慢”我正在做的事情。

我可以用 Sleep(); 来做到这一点吗?因为我不确定这是否也会“暂停”Skype 和我的程序之间的连接。

总结一下:我正在执行一个包含大量条目的操作,并且由于条目量很大,我的程序挂起很长时间,并最终崩溃(有时)。有没有办法防止这种情况发生?

顺便说一句,Skype4COM 是 STA。

  • 谢谢!

最佳答案

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

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

确保线程调用 CoInitialize在创建 COM 对象并调用 CoUnitialize 之前当它完成时。您可以找到在线程中使用 COM 的示例 here ;该文章引用了 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;

关于delphi - 使用 COM (SKYPE4COM) 执行耗时任务时防止崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5364371/

相关文章:

android - SQLite 数据库部署到 Android 设备的路径是什么?

delphi - 无需 iOS 硬件即可创建 iOS 软件

http - 如何解码gzip编码的html?

.net - 使用 VB.NET 处理 Excel com 对象的正确方法?

c# - 如何从 C++ dll 中删除 C# dll

c++ - 为什么 COM+ 组件的 CoCreation 失败并显示 0x8007007e "The specified module could not be found"?

javascript - 在javascript中设置工作目录

c# - 如何以编程方式检查安装了哪个版本的 WMI

.net - 提示用户从浏览器安装 ActiveX/.Net 类库

javascript - 从本地读取txt文件放入数组并数组放入<select>