我正在使用Skype4COM控件。我的程序试图使用For循环从Skype中的联系人列表中删除大约3K个联系人,但是
1)需要很多时间
2)它可能会崩溃,“MyApp已停止工作”
我的猜测是,我需要“减慢”我正在做的事情。
我会用Sleep()做到这一点吗?因为我不确定这是否会“暂停”Skype和我的程序之间的连接。
总结一下:我正在用大量的条目做一个动作,由于这个大的数量,我的程序挂了很长时间,并最终崩溃(有时)。有没有办法防止这种情况?
Skype4COM顺便提一下STA。
答案 0 :(得分:6)
将处理移动到单独的线程中。您的问题似乎是Windows认为应用程序已停止响应,因为它没有处理它的消息循环。
调用Application.ProcessMessages
是错误的解决方案,因为它比您想象的要多得多。您最终可能会遇到重入问题或者您不期望发生的事情。
确保线程在创建COM对象之前调用CoInitialize,并在完成后调用CoUnitialize。您可以在线程here中找到使用COM的示例;本文引用了ADO,但演示了CoInitialize/CoUninitialize
的使用。
// 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;
答案 1 :(得分:0)
如果你使用循环来删除每个联系人,你可以调用Application.ProcessMessages这应该解决问题
[编辑] 调用应该在循环中