| Autor |
Beitrag |
Bergmann89
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Di 29.03.11 17:23
Hey,
ich steh mal wieder vor nem Problem mit Threads (wie so oft in letzter Zeit). Ich hab ne Art ThreadPool (ist selbst ein Thread), der ein OLEExcelObject anlegt. In diesem Objekt legen die Workthreads dann ihre Daten ab. Wenn ich die Tabelle dann speichern will (im Context des ThreadPools) kommt folgende Meldung: EOleSysError: 'Eine Schnittstelle, die für einen anderen Thread marshalled war, wurde von der Anwendung aufgerufen.'
Mit der Meldung kann ich aber nich wirklich was anfangen. Hier mal noch ein Auzug aus dem Code zum Excel-Objekt:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67:
| function TExcelFile.WriteTipPlanData(TPData: TTipPlanData; Caption, SheetName: String; TipCharCount: PTipCharCount): Cardinal; var Sheet: Variant; p: PSheetData; Col, Row, i, j: Integer; WaitResult: Cardinal; Arr: TArray3b; begin WaitResult := WaitForSingleObject(fWriteTipPlanDataSem, SEMAPHORE_WAIT_TIME); try case WaitResult of WAIT_OBJECT_0: begin WAIT_TIMEOUT: begin result := EXCEL_FILE_WAIT_FOR_SEM_TIMEOUT; end; else result := EXCEL_FILE_WAIT_FOR_SEM_ERROR; end; finally if not ReleaseSemaphore(fWriteTipPlanDataSem, 1, nil) then result := EXCEL_FILE_RELEASE_SEM_ERROR; end; end;
procedure TExcelFile.Save(Filename: String); begin fWorkbook.SaveAs(Filename); end;
constructor TExcelFile.Create(ReqTipChars: TTipPlan; GameCount: Byte); begin inherited Create;
fWriteTipPlanDataSem := CreateSemaphore(nil, 1, 1, ''); CoInitializeEx(nil, COINIT_MULTITHREADED); fExcel := CreateOleObject('Excel.Application'); fExcel.Application.SheetsInNewWorkBook := 1; fExcel.Workbooks.Add; fWorkbook := fExcel.Workbooks[1]; end;
destructor TExcelFile.Destroy; var i: Integer; begin for i := 1 to fExcel.Workbooks.Count do fExcel.Workbooks[i].Close(False); fExcel.Quit; inherited Destroy; end; |
Weiß da jmd was ich falsch gemacht hab und kann mir da weiterhelfen?
MfG & Thx Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
Chemiker
      
Beiträge: 194
Erhaltene Danke: 14
XP, Vista 32 Bit, Vista 64 Bit, Win 7 64 Bit, Win 10, Win 11
BDS 2006, RAD Studio 2009+C++, Delphi 13, VS 2010 Prof.
|
Verfasst: Mi 30.03.11 00:45
Hallo Bergmann89,
ob der Fehler im Thread liegt kann ich an Hand des Quelltextes nicht sagen. Aufgefallen ist mir allerdings das eine Verbindung zu einem Worbook nicht ordnungsgemäß getrennt wird.
Mit dieser Quellcodezeile wird der Variable fWorkbook ein Workbook zugewiesen.
Delphi-Quelltext 1:
| fWorkbook:= fExcel.Workbooks[1]; |
aber in Destroy nicht wieder freigeben. Die Verbindung wird auch nach einem Close weiter aufrecht erhalten. Wenn jetzt die Verbindung zu Excel beendet wird bleibt die Verbindung weiter bestehen. (Kannst Du überprüfen wenn Du den Taskmanager aufrufst)
Um die Verbindung zu schließen bittet sich an das wie folgt zu realisieren:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if (NOT VarIsEmpty(fWorkbook)) then begin fWorkbook.Close; fWorkbook:= Unassigned; end; | anschließend dann mit:
Delphi-Quelltext 1: 2: 3: 4: 5:
| if NOT VarIsEmpty(fExcel) then begin fExcel.Quit; fExcel:= Unassigned; end; | Excel zu schließen.
Bis bald Chemiker
|
|
Bergmann89 
      
Beiträge: 1742
Erhaltene Danke: 72
Win7 x64, Ubuntu 11.10
Delphi 7 Personal, Lazarus/FPC 2.2.4, C, C++, C# (Visual Studio 2010), PHP, Java (Netbeans, Eclipse)
|
Verfasst: Mi 30.03.11 09:21
Hey,
danke für den Tipp, aber das hab ich im destructor alles drin stehen und Excel wird auch richtig beendet (kein Prozess mehr im Taskmanager). Den Test auf VarIsEmpty werd ich noch einfügen, den hab ich vergessen. Der Feler tritt ja beim Speichern auf, nicht beim schließen...
MfG Bergmann.
_________________ Ich weiß nicht viel, lern aber dafür umso schneller^^
|
|
|