Board index » delphi » Where to put CoInitializeEx?

Where to put CoInitializeEx?


2007-01-06 02:25:56 AM
delphi225
I just moved my web application to Delphi 2006 (which was a chore in itself,
but anyway). After I got it compiled, I ran it. It is a Web App De{*word*81}
app. When I finally got it to run, I got an error about CoInitialze wasn't
called. I suffered from this problem in the past and had fixed code to
handle that. Now it doesn't work again. I have changed machines and just
installed Delphi 2006 so it is the first time I have run it in this
environment (XP SP2). What I did before was put the CoInitializeEx in the
OnCreate event and put the CoUninitialize in the On Destroy.
The error is happening when an ADOConnection object on the WebModule is
created. I see it create the ADO connection once without problems on one
thread ID. Then I see the connection being created again on a second thread
and this time the complaint.
Anybody have any clues here?
From what I can read, people seem to think every thread needs its own
CoInitialize, but I don't even see where the WebBroker is creating the
thread so it is hard to try to add some extra code to do the initialization.
Surely everyone comes up against this problem. How do you solve it?
I think when I use the same web module in an ISAPI app instead of Web
De{*word*81} app, I didn't use to have to do the initialization myself. I think
some unit took care of it. But now I can not debug...
 
 

Re:Where to put CoInitializeEx?

I figured it out.
Previous to 2006, I did the CoInitializeEx and CoUninitialze in the OnCreate
and OnDestroy events.
I noticed in the call stack trace that the error message was coming as the
ADOConnection object on the webmodule was being streamed in by a thread. I
could see that the webmodule Create method was called before the error and
the OnCreate was never called.
So I overrode the Create and Destroy methods and moved my Com stuff in
those. So far, it seems to work okay in the WebAppDe{*word*81}.
If anyone knows any problems with doing it this way, let me know. Thanks.
 

Re:Where to put CoInitializeEx?

I do the following:
First up I include a unit in the project's dpr file, near the top:
-------------------------------------
unit ComInit;
interface
uses
ActiveX;
implementation
initialization
CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
CoUninitialize;
end.
-------------------------------------
Then in my WebModule I have a ADOConnection property that creates the
adoconnection and call coinitialize if needed, I don't use OnBeforeDispatch
because all the actions might not need ado.
property ADOConnection : TADOConnection read GetADOConnection;
function TWebModule1.GetADOConnection: TADOConnection;
begin
if NOT Assigned(FADOConnection) then
begin
CoInitialize(nil);
FADOConnection := TADOConnection.Create(nil);
with FADOConnection do begin
ConnectionString :=
'Provider=SQLOLEDB.1;Password='+DatabasePassword+';Persist Security
Info=True;'+
'User ID='+DatabaseLogin+';Initial Catalog='+DatabaseName+';Data
Source='+DatabaseServer+';Use Procedure for Prepare=1;'+
'Auto Translate=True;Packet Size=4096;'+
'Tag with column collation when possible=False';
LoginPrompt := False;
Provider := 'SQLOLEDB.1';
end;
FADOConnection.Open;
end;
Result := FADOConnection;
end;
Use OnAfterDispatch for cleanup.
procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
if Assigned(FADOConnection) then
begin
FADOConnection.Close;
FADOConnection.Free;
FADOConnection := nil;
CoUnInitialize;
end;
end;
I use this kind of setup with webbroker apache dso modules and it works
great. I have tried a few other ways, but something always seems to break.
DD
 

Re:Where to put CoInitializeEx?

Thanks for your suggestion. So far, just putting it in the module create
and destroy overrides seems to solve the problem. At least it does in Web
App De{*word*81}. Haven't tried in IIS yet, but I think IIS is supposed to do
the CoInitialize in that circumstance.
"Dan Downs" <XXXX@XXXXX.COM>writes
Quote
I do the following:

First up I include a unit in the project's dpr file, near the top:

-------------------------------------
unit ComInit;

interface

uses
ActiveX;

implementation

initialization
CoInitializeEx(nil,COINIT_MULTITHREADED);
finalization
CoUninitialize;
end.
-------------------------------------

Then in my WebModule I have a ADOConnection property that creates the
adoconnection and call coinitialize if needed, I don't use
OnBeforeDispatch because all the actions might not need ado.

property ADOConnection : TADOConnection read GetADOConnection;

function TWebModule1.GetADOConnection: TADOConnection;
begin
if NOT Assigned(FADOConnection) then
begin
CoInitialize(nil);
FADOConnection := TADOConnection.Create(nil);
with FADOConnection do begin
ConnectionString :=
'Provider=SQLOLEDB.1;Password='+DatabasePassword+';Persist Security
Info=True;'+
'User ID='+DatabaseLogin+';Initial Catalog='+DatabaseName+';Data
Source='+DatabaseServer+';Use Procedure for Prepare=1;'+
'Auto Translate=True;Packet Size=4096;'+
'Tag with column collation when possible=False';
LoginPrompt := False;
Provider := 'SQLOLEDB.1';
end;
FADOConnection.Open;
end;
Result := FADOConnection;
end;

Use OnAfterDispatch for cleanup.

procedure TWebModule1.WebModuleAfterDispatch(Sender: TObject;
Request: TWebRequest; Response: TWebResponse; var Handled: Boolean);
begin
if Assigned(FADOConnection) then
begin
FADOConnection.Close;
FADOConnection.Free;
FADOConnection := nil;
CoUnInitialize;
end;
end;


I use this kind of setup with webbroker apache dso modules and it works
great. I have tried a few other ways, but something always seems to break.

DD