Programm hinterlässt Prozess, obwohl beendet



  • Hallo,

    @Braunstein: Danke für die Mail, ist angekommen.

    Ich habe mich im letzten Posting falsch ausgedrückt. Ich kann auf die Excel-Instanz zugreifen, aber der Zugriff scheint ins leere zu gehen. Jeder Versuch,
    eine Eigenschaft zu verwenden, führt zu nichts. Die Funktionen werden nicht ausgeführt, es kommt keine Fehlermeldung, der Aufruf von GetLastError() liefert 0, der Thread wird beendet.

    Ich weiß echt keinen Rat mehr.

    Gruß Udo_11



  • Ich würde deinen Thread etwas umorganisieren

    class XLSSearch : public TThread
    {
    private:
      .
      .
      .
      TMLWorkbook *WorkBook; //Bezeichnung Excel ist etwas mißdeutlich
    protected:
      void __fastcall Execute();
    public:
      __fastcall XLSSearch(TMLWorkbook *Xls);
    };
    
    __fastcall XLSSearch::XLSSearch(TMLWorkbook *Xls) : TThread(false), WorkBook(Xls) // WorkBook sollte schon im Konstruktor initialisiert werden, woanders geht es ja nicht
    {
      Priority = tpNormal;
      FreeOnTerminate = true;
    }
    

    Hier muß natürlich sichergestellt werden, dass WorkBook immer auf eine gültige Instanz zeigt. Also Excel vorher nicht löschen.



  • Hallo,

    @Braunstein: Habe Deinen Änderungsvorschlag eingearbeitet. Am Verhalten ändert sich jedoch nichts.

    an einem Breakpoint im Debugger bekomme ich bei überwachten Ausdrücken folgende Ausgabe:

    WorkBook: :01B2D2B0
    WorkBook->WorksheetCount: E2122 Funktionsaufruf durch unbehandelte Exception 0xeedfade an Adresse 0x7c812a5b beendet
    WorkBook->Sheets[0]->Name: E2122 Funktionsaufruf durch unbehandelte Exception 0xeedfade an Adresse 0x7c812a5b beendet

    Das bedeutet doch, das Workbook auf eine Speicheradresse zeigt, aber nicht verwendet werden kann ???

    Gruß Udo_11



  • Nun, das Workbook muß natürlich existieren. Debugge mal von dem Punkt aus, wo das Workbook erzeugt wird.



  • Hallo,

    Beim Debuggen ab dem Zeitpunkt der Erstellung der Excel-Instanz sieht das folgendermaßen aus:

    Breakpoint Excel-Initialisierung --> Ok
    Breakpoint im Konstruktor des Threads: WorkBook existiert (Adresse: 01B2D2B0) und ich kann in überwachten Ausdrücken alle Funktionen des WorkBook aufrufen.

    Breakpoint am Beginn der Execute-Methode des Threads: WorkBook-Adresse ist die gleiche, aber beim Zugriff auf die Funktionen des WorkBooks kommen die im letzten Posting gezeigten Fehler.

    Gruß Udo_11



  • Dann scheint das Workbook irgendwo dazwischen freigegeben worden zu sein. Schau dir mal alle Funktionen an, mit denen man das Workbook freigebn kann. Setze gegebenenfalls Breakpoints in die Destruktoren von TMLWorkBook sowie TMLExcel und schau ob und wann die aufgerufen werden.



  • Hallo,

    @Braunstein: Nach Deinem Hinweis von gestern habe habe ich den Debugger nochmal bemüht und folgendes festgestellt:

    Im Konstruktor des Threads ist ein Zugriff auf WorkBook->Name möglich

    Die Excel-Instanz wird bei mir nur in der Funktion gelöscht, welche ich dem OnTerminate-Ereignis des Threads zugewiesen habe.

    OnTerminate wird laut Builder-Hilfe ausgelöst, wenn die Execute-Methode des Threads zurückkehrt.

    Die Execute-Methode meines Threads wird beendet, weil sie einen Fehler beim Zugriff auf WorkBook->Name produziert.



  • Ok, ich ahne was los ist. Übergib mal statt der Workbookinstanz die Excelinstanz an deinen Thread. Die Excelinstanz verwaltet ja die Workbooks und da kann es evtl. vorkommen, dass der Pointer auf ein Workbook intern gelöscht und neu erzeugt wird. Dann hättest du einen ungültigen Pointer in deinem Thread.



  • Hallo,

    Bei der Übergabe der Excel-Instanz an den Thread zeigt sich das gleiche Fehlerbild.

    Der Fehler wird ausgelöst in der TMLExcel-Klasse in der Funktion GetWorkbookCount()

    int TMLExcel::GetWorkbookCount()
    {
      if(!Connect)
       return 0;
      else
       return var_Excel.OlePropertyGet("Workbooks").OlePropertyGet("Count");  //in dieser Zeile !!!
    }
    

    Gruß Udo_11



  • Hallo,

    Ich habe jetzt folgende Fehlermeldung:

    Fehler:
    Eine Schnittstelle, die für einen anderen Thread marshalled war, wurde von der Anwendung aufgerufen

    Das ganze hat mit Marshalling und COM+ zu tun. Ich habe auch schon etliche Artikel im Netz gefunden, weiß aber nicht so recht wie man das im konkreten Fall umsetzen muß.
    Wenn dazu jemand etwas sagen kann, wäre das wunderbar.

    Gruß Udo_11



  • Hallo,

    für alle, die es vielleicht interessiert. Ich habe jetzt eine Variante gefunden, bei welcher das Durchsuchen einer Exceldatei in einem eigenen Thread funktioniert.

    Das Excel-Objekt wird im Thread initialisiert.

    void __fastcall XLSSearch::Execute()
    {
      OleCheck(CoInitialize(NULL));
    
      try
      {
        FExcel = new TMLExcel;
        FExcel->OpenWorkbook(MainForm->datapath+FileName);
        FExcel->CloseExcelOnTerminate = true;
        FExcel->Books[0]->Saved = true;  // damit beim Schließen von Excel kein Speichern-Dialog eingeblendet wird
    
        try
        {
          ExcelSuche([Parameter]); // hier werden auch Parameter übergeben
        }
        catch(Exception &e)
        {
          msg = "Fehler beim Start der ExcelSuche():";
          Synchronize(WriteMsg);   //Eintrag in eine log-Datei
          msg = e.Message;
          Synchronize(WriteMsg);   //Eintrag in eine log-Datei
        }
      }
      __finally
      {
        delete FExcel;
        FExcel = NULL;
        CoUninitialize;
      }
    }
    //---------------------------------------------------------------------------
    

    Die Funktion, die dem OnTerminate des Threads zugewiesen ist:

    void __fastcall XLSSearch::DeleteThread(TObject *Sender)
    {
      delete FExcel;
      FExcel = NULL;
      CoUninitialize;
      Flog->Add("Thread beendet.");
    }
    //---------------------------------------------------------------------------
    

    Sooft ich getestet habe, wurde Excel ordnungsgemäß geschlossen und auch der Prozess jedesmal beendet.


Anmelden zum Antworten