我正在使用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/