开发者

Preventing crash when doing time consuming task with COM (SKYPE4COM)

I am using the Skype4COM control. My program is trying to delete around 3K contacts from my contact list in Skype using a For loop, however

1) It takes a lot of time

2) it may crash, with a "MyApp has stopped working"

My guess is that somehow I need to "slow down" what I am doing.

Would I do that with Sleep();? Because I am not sure if that is also gonna "pause" the connection between Skype and my program.

To summarize: I am d开发者_如何学Gooing an action with a huge ammount of entries, and because of that big ammount, my program is hanging for a long time, and eventually crashes (sometimes). Is there a way to prevent that?

Skype4COM is STA by the way.

  • Thanks!


Move the processing into a separate thread. Your problem appears to be that Windows thinks the app has stopped responding because it's not processing it's message loop.

Calling Application.ProcessMessages is the wrong solution, because it does a lot more than you might think. You can end up with problems with reentrancy, or things happening that you don't expect.

Make sure that the thread calls CoInitialize before it creates the COM object, and calls CoUnitialize when it's done. You can find examples of using COM in a thread here; the article refers to ADO, but demonstrates the use of CoInitialize/CoUninitialize.

EDIT: After the comments, I'm adding an example of receiving a custom message in a Delphi app. The thread will need access to the UM_IDDELETED constant; you can do this by (preferably) adding it to a separate unit and using that unit in both your main form's unit and the thread's unit, or simply by defining it in both units.

// 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;


if you are using a loop to delete each contact you can place a call to Application.ProcessMessages this should fix the issue

[edit] the call should be in the loop

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜