2012-02-11 2 views
2

Мне нужно сделать многолетнюю задачу в фоновом режиме. Я использую OmniThreadLibrary, прыгая, это может мне помочь.Ошибка DBX: Драйвер не может быть правильно инициализирован при использовании OmniThreadLibrary (но нормально в противном случае)

Я использую драйвер dbexpress + mssql. Я могу подключить нормально, когда в главном потоке, но получить:

Project Project1.exe raised exception class TDBXError with message 'DBX Error: Driver could not be properly initialized. Client library may be missing, not installed properly, of the wrong version, or the driver may be missing from the system path.'.

Соединения создаются в каждом потоке, а не общий DataModule:

type 
    TdbManager = class(TObject) 
    private 
    { private declarations } 
    FCon: TSQLConnection; 
    public 
    { public declarations } 
    procedure Open(Driver:String; aparams:TStringList);overload; 
    procedure Close; 

    constructor Create; 
    destructor Destroy;override; 
    end; 

    constructor TdbManager.Create; 
begin 
    inherited Create; 
    FCon := TSQLConnection.Create(nil); 
end; 

procedure TdbManager.Open(Driver: String; aparams: TStringList); 
var 
    i: Integer; 
    key:string; 
begin 
    FCon.DriverName := Driver; 

    for i := 0 to params.Count - 1 do 
    begin 
    key := params.Names[i]; 
    FCon.Params.Values[key] := params.Values[key]; 
    end; 

    LogMsg('Open DB '+ Driver + ': ' + FHost + '\' + FDatabase); 

    FCon.Open; 
    LogMsg('Done.'); 
end; 

И фоновая задача выполнена:

procedure TBackupPlan.OnScheduleTrigger(Sender: TScheduledEvent); 
begin 
    Parallel.Async(procedure 
    begin 
    ExecuteDataTask(Sender.Name); 
    end); 
end; 

procedure TBackupPlan.ExecuteDataTask(const Name: String); 
var 
    db:TdbManager; 
begin 
    db := nil; 

    db := TSqlServerManager.Create; 
    db.Open(self.Driver, options); 

    result := db; 
end; 

Если я выполняю это непосредственно, откройте ОК. Если я использую Parallel.Async, то получите ошибку. Что здесь происходит?

ответ

7

Я нашел информацию об этом здесь:

http://docwiki.embarcadero.com/RADStudio/en/DbExpress_Database_Specific_Information

MSSQL Driver Requires Calls to CoInitialize and CoUninitialize for Console Applications and Worker Threads

The MSSQL driver does not call CoInitialize or CoUninitialize. Earlier versions of the MSSQL driver, which is a COM driver, called CoInitialize and CoUninitialize directly, which is not a good practice. VCL applications take care of these calls for you, so VCL applications do not require calling CoInitialize and CoUninitialize. However, applications using the MSSQL driver in console applications or in worker threads need to call CoInitialize/CoUninitialize. If this call is not made, you will see the following error message: "DBX Error: Driver could not be properly initialized. Client library may be missing, not installed properly, of the wrong version, or the driver may be missing from the system path." For help on CoInitialize, see the CoInitialize Function on MSDN.