Thread erstellt und dennoch ungültiger Speicherzugriff

Anfängerfragen zum Programmieren mit PureBasic.
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Okay dann hier mal der Code, bitte mir nicht gleich jeden Fehler gleich um die Ohren hauen :lol:

Also ich erkläre mal kurz den Programmablauf, dann wird der Code evtl. verständlicher.

1. Das Programm wird gestartet
2. Der User gibt den Quell Pfad und den Ziel Pfad an, außerdem noch die Spalte der Dateien in welcher die erforderlichen Daten sind.
3. Es wird damit begonnen die 1.Datei einzulesen, aus der Spalte die der User angegeben hat werden die Daten gefiltert und in einer Variable (sendungsnummern$) gespeichert (diese Daten werden benötigt für die SQL-Abfrage)
4. Nachdem die Datei komplett gelesen wurde und die benötigten Dateien in einer Variable gespeichert sind wird die Verbindung zur Datenbank aufgebaut.
5. Übergeben wird das Select mit der Variable die die Daten aus der gelesenen Datei enthält.
(sql_abfrage$="select blablabla From blablabla Where substring(d.paketlabel from 1 for 11) in ("+sendungsnummern$+")")
6. Wurde die Datenbankabfrage erfolgreich beendet werden die Daten nun in eine Datei geschrieben
7. Jetzt wird die nächste Datei eingelesen...

Und hier der Code, ich hoffe ihr versteht ihn ein wenig. Bestimmt nicht gut programmiert aber er funktioniert bis auf das mit dem Thread :lol: .

Code: Alles auswählen

EnableExplicit
UsePostgreSQLDatabase()
UseODBCDatabase()
UsePNGImageDecoder()

Structure ThreadData
  thread_sql_abfrage.s
  thread_dateipfad.s
  thread_dateiname.s
  thread_ziel_verzeichnis.s
EndStructure

Declare main()
Declare verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
Declare dateien_erzeugen(dateipfad$)
Declare sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
Declare sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
Declare Thread(*tData.ThreadData)

Global anzahl_nbgut=0
Global nbgut_kennzeichen_spalte
Global nbgut_kennzeichen
Global sendungsnummer_spalte
Global Hauptfenster=0

Global button_info = CatchImage(#PB_Any, ?INFO)
ResizeImage(button_info, 40, 40)

DataSection
  INFO:
  IncludeBinary "info.png"
EndDataSection

main()

Procedure main()
  Protected Button_Quell_Pfad, String_Quell_Pfad, Button_Create_Files, Button_Abbrechen, Text_NB_Gut_Kz_Spalte, String_NB_Gut_Kz_Spalte, Text_NB_Gut_Kz, String_NB_Gut_Kz, Text_Sendungsnr_Spalte, String_Sendungsnr_Spalte, Button_Ziel_Pfad, String_Ziel_Pfad
  Protected Frame_1, Option_Ja, Option_Nein, ButtonImage_Info
  Protected Event
  Protected quell_verzeichnis$, ziel_verzeichnis$, verzeichnishandle, verzeichnisname$
  Protected dateiendung$ =".csv"
  Protected s.l
  Protected eingaben_ok=1
  
  If OpenWindow(Hauptfenster, 0, 0, 500, 230, "GLS NB-Gut Filtern", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_MinimizeGadget)
    
    Button_Quell_Pfad = ButtonGadget(#PB_Any, 10, 10, 110, 22, "Quelle auswählen")
    String_Quell_Pfad = StringGadget(#PB_Any, 130, 11, 360, 20, "")
    Text_NB_Gut_Kz= TextGadget(#PB_Any, 135, 58, 150, 20, "NB-Gut Kennzeichen:", #PB_Text_Right)
    String_NB_Gut_Kz= StringGadget(#PB_Any, 290, 55, 20, 20, "2")
    SetGadgetAttribute(String_NB_Gut_Kz, #PB_String_MaximumLength, 2) 
    Text_NB_Gut_Kz_Spalte= TextGadget(#PB_Any, 135, 88, 150, 20, "NB-Gut Kennzeichen in Spalte:", #PB_Text_Right)
    String_NB_Gut_Kz_Spalte= StringGadget(#PB_Any, 290, 85, 20, 20, "8", #PB_String_Numeric)
    SetGadgetAttribute(String_NB_Gut_Kz_Spalte, #PB_String_MaximumLength, 2)
    Text_Sendungsnr_Spalte= TextGadget(#PB_Any, 135, 118, 150, 20, "Sendungsnummer in Spalte:", #PB_Text_Right)
    String_Sendungsnr_Spalte= StringGadget(#PB_Any, 290, 115, 20, 20, "4", #PB_String_Numeric)
    SetGadgetAttribute(String_Sendungsnr_Spalte, #PB_String_MaximumLength, 2)
    Frame_1 = FrameGadget(#PB_Any, 340, 65, 150, 55, "Ordner Rekursiv scannen")
    Option_Ja = OptionGadget(#PB_Any, 375, 85, 30, 25, "ja")
    Option_Nein = OptionGadget(#PB_Any, 430, 85, 40, 25, "nein")
    Button_Ziel_Pfad = ButtonGadget(#PB_Any, 10, 160, 110, 22, "Ziel auswählen")
    String_Ziel_Pfad = StringGadget(#PB_Any, 130, 161, 360, 20, "")
    Button_Abbrechen = ButtonGadget(#PB_Any, 390, 200, 100, 22, "Abbrechen")
    Button_Create_Files = ButtonGadget(#PB_Any, 280, 200, 100, 22, "Dateien erstellen")
    ButtonImage_Info = ButtonImageGadget(#PB_Any, 20, 70, 50, 50, ImageID(button_info))
    s.l=GetWindowLong_(GadgetID(ButtonImage_Info), #GWL_STYLE)
    SetWindowLong_(GadgetID(ButtonImage_Info.i), #GWL_STYLE, #BS_FLAT | #BS_OWNERDRAW | s)
    SetGadgetState(Option_Ja, 1)
  EndIf
  
  Repeat 
    Event = WaitWindowEvent()
    
    If Event=#PB_Event_Gadget
      Select EventGadget()
        Case Button_Quell_Pfad
          quell_verzeichnis$=PathRequester("Bitte wählen Sie einen Pfad aus", "")
          SetGadgetText(String_Quell_Pfad, quell_verzeichnis$)
        Case Button_Ziel_Pfad
          ziel_verzeichnis$=PathRequester("Bitte wählen Sie einen Pfad aus", "")
          SetGadgetText(String_Ziel_Pfad, ziel_verzeichnis$)
        Case Button_Create_Files
          ziel_verzeichnis$=GetGadgetText(String_Ziel_Pfad)
          quell_verzeichnis$=GetGadgetText(String_Quell_Pfad)
          
          If GetGadgetText(String_Quell_Pfad) =""
            MessageRequester("Info", "Bitte Quell Ordner auswählen")
            eingaben_ok=0
          EndIf
          
          If GetGadgetText(String_NB_Gut_Kz) =""
            MessageRequester("Info", "Bitte NB-Gut Kennzeichen angeben")
            eingaben_ok=0
          EndIf  
          
          If GetGadgetText(String_NB_Gut_Kz_Spalte) =""
            MessageRequester("Info", "Bitte Spalte für NB-Gut Kennzeichen angeben")
            eingaben_ok=0
          EndIf  
          
          If GetGadgetText(String_Sendungsnr_Spalte) =""
            MessageRequester("Info", "Bitte Spalte für Sendungsnummer angeben")
            eingaben_ok=0
          EndIf  
          
          If GetGadgetText(String_Ziel_Pfad) =""
            MessageRequester("Info", "Bitte Ziel Ordner auswählen")
            eingaben_ok=0
          EndIf
          
          If quell_verzeichnis$ <> "" And ziel_verzeichnis$ <> "" And dateiendung$ <> "" And eingaben_ok=1
            
            nbgut_kennzeichen_spalte=Val(GetGadgetText(String_NB_Gut_Kz_Spalte))
            nbgut_kennzeichen=Val(GetGadgetText(String_NB_Gut_Kz))
            sendungsnummer_spalte=Val(GetGadgetText(String_Sendungsnr_Spalte))
            
            Debug "NB_Gut_Kennzeichen: "+nbgut_kennzeichen
            Debug "NB_Gut_Kennzeichen_Spalte: "+nbgut_kennzeichen_spalte
            Debug "Sendungsnummer Spalte: "+sendungsnummer_spalte
            
            quell_verzeichnis$=GetGadgetText(String_Quell_Pfad)
            Debug quell_verzeichnis$
            ;DisableWindow(0, #True)
            verzeichnishandle = ExamineDirectory(#PB_Any, quell_verzeichnis$, dateiendung$)
            verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
          EndIf
          
        Case ButtonImage_Info
          MessageRequester("Info", "Das Programm filtert alle Sendungsnummern und zugehörige Artikelnummern heraus, welche von .....usw.")          
          
        Case Button_Abbrechen
          SetGadgetText(String_Quell_Pfad, "")
          SetGadgetText(String_Ziel_Pfad, "")
          SetGadgetText(String_NB_Gut_Kz, "")
          SetGadgetText(String_NB_Gut_Kz_Spalte, "")
          SetGadgetText(String_Sendungsnr_Spalte, "")
          SetGadgetText(String_Ziel_Pfad, "")
      EndSelect
    EndIf
  Until Event = #PB_Event_CloseWindow
EndProcedure

Procedure.i verzeichnis_scannen(quell_verzeichnis$, dateiendung$, ziel_verzeichnis$)
  Debug "Verzeichnis: "+quell_verzeichnis$
  Debug "Dateiendung: "+dateiendung$
  Protected verzeichnishandle 
  Protected verzeichnisname$
  Protected modifydatum$
  Protected dateiname$
  Protected dateipfad$
  Protected scan_rekursiv=1
  Protected endung$
  
  If Right(quell_verzeichnis$, 1) <> "\" And Right(quell_verzeichnis$, 1) <> "/"
    quell_verzeichnis$ = quell_verzeichnis$+"\"
  EndIf
  verzeichnishandle = ExamineDirectory(#PB_Any, quell_verzeichnis$, "*.*")
  
  If scan_rekursiv =1
    Debug "Rekursiv Scannen!"
    If verzeichnishandle <> 0
      
      While NextDirectoryEntry(verzeichnishandle)
        verzeichnisname$ = DirectoryEntryName(verzeichnishandle)
        If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_Directory
          If verzeichnisname$ <> "." And verzeichnisname$ <> ".."
            verzeichnis_scannen (quell_verzeichnis$+verzeichnisname$, dateiendung$, ziel_verzeichnis$)
          EndIf
        EndIf
        If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_File
          dateipfad$=quell_verzeichnis$+DirectoryEntryName(verzeichnishandle)
          dateiname$=DirectoryEntryName(verzeichnishandle)
          Debug dateipfad$
          Debug dateiname$
          If GetExtensionPart(dateipfad$) = "csv"
            sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
            anzahl_nbgut=0
          EndIf
        EndIf
      Wend
      FinishDirectory(verzeichnishandle)
    EndIf
    
  ElseIf scan_rekursiv = 0
    Debug "Nicht rekursiv scannen!"
    If verzeichnishandle <> 0
      
      While NextDirectoryEntry(verzeichnishandle)
        verzeichnisname$ = DirectoryEntryName(verzeichnishandle)
        If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_Directory

        EndIf
        If DirectoryEntryType(verzeichnishandle) = #PB_DirectoryEntry_File
          
        EndIf
      Wend
      
      FinishDirectory(verzeichnishandle)
    EndIf
  EndIf
  If verzeichnishandle = 0
    MessageRequester("Info", "Fehler: Keine Dateien im Quell-Verzeichnis gefunden")
  EndIf
  
EndProcedure

Procedure sql_scripte_erstellen(dateipfad$, dateiname$, ziel_verzeichnis$)
  Protected sql_abfrage$
  Protected zeile$
  Protected sendungsnummer$=""
  Protected sendungsnummern$=""
  Protected csv_file
  Protected Thread
  Protected i
  Protected test
  
  If ReadFile(0, dateipfad$)                                                                           ; wenn die Datei geöffnet werden konnte, setzen wir fort...
    While Eof(0) = 0                                                                                   ; sich wiederholende Schleife bis das Ende der Datei ("end of file") erreicht ist
      zeile$ = ReadString(0, #PB_Ascii)   ; Zeile für Zeile im Debugger-Fenster anzeigen
      If StringField(zeile$, nbgut_kennzeichen_spalte, ";") = Str(nbgut_kennzeichen)
        sendungsnummer$= StringField(zeile$, sendungsnummer_spalte, ";")
        anzahl_nbgut+1
        
        If anzahl_nbgut=1 
          sendungsnummern$="'"+sendungsnummer$+"'"
        Else
          sendungsnummern$=sendungsnummern$+","+"'"+sendungsnummer$+"'"
        EndIf
        
      EndIf
    Wend
    Debug "Anzahl NB-Gut: "+anzahl_nbgut
    Debug "Sendungsnummern: "+sendungsnummern$
    If sendungsnummern$ <> ""
      sql_abfrage$="select blablabla From blablabla Where substring(d.paketlabel from 1 for 11) in ("+sendungsnummern$+")"
      Debug sql_abfrage$
      ;DisableWindow(Hauptfenster, #True)
      Define *tData.ThreadData = AllocateStructure(ThreadData)
      *tData\thread_sql_abfrage=sql_abfrage$
      *tData\thread_dateipfad=dateipfad$
      *tData\thread_dateiname=dateiname$
      *tData\thread_ziel_verzeichnis=ziel_verzeichnis$
      Thread = CreateThread(@Thread(), *tData)
      ;sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
    EndIf
    CloseFile(0)
  Else
    MessageRequester("Information","Konnte Datei nicht öffnen!")
  EndIf
EndProcedure

Procedure Thread(*tData.ThreadData)
  sql_abfrage_ausfuehren(*tData\thread_sql_abfrage,*tData\thread_dateipfad, *tData\thread_dateiname, *tData\thread_ziel_verzeichnis)
  FreeMemory(*tData)
EndProcedure

Procedure sql_abfrage_ausfuehren(sql_abfrage$, dateipfad$, dateiname$, ziel_verzeichnis$)
  Protected export_datenbank$="host=x.x.x.x port=xxxx dbname=xxxxx" ;LIVE DATENBANK!!!
  Protected anzahl_spalten=0
  Protected speicherpfad$
  Protected i
  Protected spalten_typ$
  Protected anzahl_datensaetze
  Protected datensatz$
  Protected csv_file
  Protected abfrage$
  Protected thread
  
  If Right(ziel_verzeichnis$, 1) <> "\" And Right(ziel_verzeichnis$, 1) <> "/"
    ziel_verzeichnis$ = ziel_verzeichnis$+"\"
  EndIf
  speicherpfad$=ziel_verzeichnis$+dateiname$
  csv_file = CreateFile(#PB_Any, Mid(speicherpfad$, 1, Len(speicherpfad$)-4)+"_NB_Gut.csv")
  
  If csv_file
    
    If OpenDatabase(1, export_datenbank$, "xxxx", "xxxx", #PB_Database_PostgreSQL) 
      Debug "Verbindung zur Datenbank erolgreich! "+sql_abfrage$
      abfrage$=sql_abfrage$
      If DatabaseQuery(1, abfrage$) 
        anzahl_spalten = DatabaseColumns(1)              ; Gibt die Anzahl an Spalten von der letzten Datenbank-Abfrage zurück.
        Debug "Anzahl Spalten: "+ anzahl_spalten
        For i = 0 To anzahl_spalten-1
          If i=0 
            WriteString(csv_file, DatabaseColumnName(1, i),#PB_Ascii)
            spalten_typ$=spalten_typ$+DatabaseColumnType(1, i)
          EndIf
          If i > 0
            If i = anzahl_spalten-1
              WriteStringN(csv_file, ";"+DatabaseColumnName(1, i),#PB_Ascii)
              spalten_typ$=spalten_typ$+";"+DatabaseColumnType(1, i)
            Else
              WriteString(csv_file, ";"+DatabaseColumnName(1, i),#PB_Ascii)
              spalten_typ$=spalten_typ$+";"+DatabaseColumnType(1, i)
            EndIf
          EndIf  
        Next
        ;FinishDatabaseQuery(1)
        Debug spalten_typ$
        ;If DatabaseQuery(1, sql_abfrage$)
        While NextDatabaseRow(1) 
          anzahl_datensaetze=anzahl_datensaetze+1
          Debug "---------------------------"
          For i = 1 To anzahl_spalten
            
            Debug "Anzahl Spalten: "+anzahl_spalten
            If i=1 
              Debug "i=1"
              Select StringField(spalten_typ$, i, ";")
                Case "1"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
                Case "2"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
                Case "3"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
                Case "4"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
                Case "5"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
                Case "6"
                  Debug GetDatabaseString(1, i-1)
                  WriteString(csv_file, GetDatabaseString(1, i-1),#PB_Ascii)
              EndSelect
            EndIf
            If i > 1
              If i = anzahl_spalten
                Debug "i=1 und gleich anzahl spalten"
                Select StringField(spalten_typ$, i, ";")
                  Case "1"
                    ;Debug GetDatabaseString(1, i-1)
                    datensatz$=GetDatabaseString(1, i-1)
                    If FindString(datensatz$, ".")
                      datensatz$=ReplaceString(datensatz$, ".", ",")
                    EndIf
                    WriteStringN(csv_file, ";"+datensatz$,#PB_Ascii)
                    Debug "Datensatz$: "+datensatz$
                  Case "2"
                    Debug GetDatabaseString(1, i-1)
                    WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "3"
                    Debug GetDatabaseString(1, i-1)
                    WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "4"
                    Debug GetDatabaseString(1, i-1)
                    WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "5"
                    Debug GetDatabaseString(1, i-1)
                    WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "6"
                    Debug GetDatabaseString(1, i-1)
                    WriteStringN(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                EndSelect
              Else
                Debug "i ist größer 1 aber kleiner anzahl spalten"
                Select StringField(spalten_typ$, i, ";")
                  Case "1"
                    ;Debug GetDatabaseString(1, i-1)
                    datensatz$=GetDatabaseString(1, i-1)
                    If FindString(datensatz$, ".")
                      datensatz$=ReplaceString(datensatz$, ".", ",")
                    EndIf
                    WriteString(csv_file, ";"+datensatz$,#PB_Ascii)
                    Debug "Datensatz$: "+datensatz$
                  Case "2"
                    Debug GetDatabaseString(1, i-1)
                    WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "3"
                    Debug GetDatabaseString(1, i-1)
                    WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "4"
                    Debug GetDatabaseString(1, i-1)
                    WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "5"
                    Debug GetDatabaseString(1, i-1)
                    WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                  Case "6"
                    Debug GetDatabaseString(1, i-1)
                    WriteString(csv_file, ";"+GetDatabaseString(1, i-1),#PB_Ascii)
                EndSelect
              EndIf
            EndIf  
          Next
        Wend
        ;Else
        ;MessageRequester("Fehler", "Kann die folgende Abfrage nicht ausführen: "+DatabaseError())
        ;EndIf
        FinishDatabaseQuery(1)
        CloseDatabase(1)
        CloseFile(csv_file)
        ;MessageRequester("CSV-Datei wurde erzeugt", "Erzeugte Datensätze: "+anzahl_datensaetze)
      Else
        MessageRequester("Fehler", "Kann die folgende Abfrage nicht ausführen: "+DatabaseError())
      EndIf
      
    Else
      Debug "Connection failed: "+DatabaseError()
      MessageRequester("Connected to PostgreSQL","Failed!")
      End
    EndIf
  Else
    MessageRequester("Information","Konnte Datei nicht erstellen!")
  EndIf
  Debug "Dateiname: "+dateiname$
  Debug "Zielverzeichnis:"+ziel_verzeichnis$
  Debug "Speicherpfad: "+speicherpfad$
EndProcedure
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von man-in-black »

Komisch, ich kann den Speicherfehler mit folgendem Code nach x-Durchläufen erzeugen [PB 5.42LTS Win7]:

Code: Alles auswählen

Structure ThreadData
  thread_sql_abfrage.s
  thread_dateipfad.s
  thread_dateiname.s
  thread_ziel_verzeichnis.s
EndStructure


Procedure Thread(*tData.ThreadData)
  Debug Str(*tData)+"    --  T"
  FreeMemory(*tData)
EndProcedure

Procedure test()
      Define *tData.ThreadData = AllocateStructure(ThreadData)
      *tData\thread_sql_abfrage=sql_abfrage$
      *tData\thread_dateipfad=dateipfad$
      *tData\thread_dateiname=dateiname$
      *tData\thread_ziel_verzeichnis=ziel_verzeichnis$
      Debug *tData
      Thread = CreateThread(@Thread(), *tData)
      
EndProcedure


For x=1 To 200
  test()  
Next
Mich wundert auch etwas, dass die letzte Debugausgabe scheinbar nichtmehr ausgeführt wird?!

Bug?

edit:
du kannst deine Datenbankanfragen auch bündeln und musst dich nicht jedesmal neu anmelden bzw. abmelden.
Das spart sicherlich Zeit und fällt später bei großen Datenmengen auf ;)

MIB
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von mhs »

In den Compiler Optionen:
[x] Thread sicheres Executable erstellen

Und das Gegenstück zu AllocateStructure ist FreeStructure:

Code: Alles auswählen

Procedure Thread(*tData.ThreadData)
  Debug Str(*tData)+"    --  T"
  FreeStructure(*tData)
EndProcedure
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von NicTheQuick »

mhs hat geschrieben:Und das Gegenstück zu AllocateStructure ist FreeStructure:
Das war mein Fehler. :)
Benutzeravatar
man-in-black
Beiträge: 362
Registriert: 21.08.2006 17:39

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von man-in-black »

Das war mein Fehler. :)
Und ich glaub das auch noch blind :lol:
(hab alles, kann alles, weiß alles!!^^)

Bild
Benutzeravatar
mhs
Beiträge: 224
Registriert: 11.01.2009 16:30
Wohnort: Graben
Kontaktdaten:

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von mhs »

man-in-black hat geschrieben:
Das war mein Fehler. :)
Und ich glaub das auch noch blind :lol:
:lol: :lol: Tja, Fehler können jedem passieren...
Michael Hack

Michael Hack Software :: Softwareentwicklung | Webentwicklung | IT-Dienstleistungen
www.michaelhacksoftware.de :: www.mh-s.de :: www.michael-hack.de
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Hallo zusammen 8) , erst einmal vielen Dank für eure Hilfe. Soweit habe ich das jetzt verstanden und auch ins Programm integriert.

Funktioniert auch soweit, nur dass das Fenster wieder 'keine Rückmeldung' anzeigt, genau das wollte ich ja umgehen mit den Thread. Kann es sein das an irgend einem Punkt bestimmte Ereignisse noch nicht abgearbeitet sind?
Habe schon versucht an gewissen Stellen ein WaitWindowEvent einzusetzen aber leider ohne Erfolg :praise:

Code: Alles auswählen

If sendungsnummern$ <> ""
      sql_abfrage$="select...from... usw"
      Debug sql_abfrage$

      DisableWindow(Hauptfenster, #True)
      
      Define *tData.ThreadData = AllocateStructure(ThreadData)
      *tData\thread_sql_abfrage=sql_abfrage$
      *tData\thread_dateipfad=dateipfad$
      *tData\thread_dateiname=dateiname$
      *tData\thread_ziel_verzeichnis=ziel_verzeichnis$
      Thread = CreateThread(@Thread(), *tData)
      
      If IsThread(Thread)
        Debug "Thread: "+Thread
        WaitThread(Thread)
      EndIf

    EndIf
    CloseFile(0)
Sollte doch aber passen oder? Es wird überprüft ob der Thread aktiv ist, ja ist er!
Mit WaitThread() gebe ich ja mit das die Programmausführung solange angehalten wird, bis der Thread abgeschlossen ist.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von NicTheQuick »

Das ist auch reichlich sinnlos, was du das machst. Du erstellst einen nebenläufigen Thread und wartest, bis er sich beendet. Damit ist jeder Sinn eines Threads hinfällig.
Du machst nichts anderes als ohne Thread:

Code: Alles auswählen

If sendungsnummern$ <> ""
	sql_abfrage$="select...from... usw"
	Debug sql_abfrage$
	
	DisableWindow(Hauptfenster, #True)
	
	Define *tData.ThreadData = AllocateStructure(ThreadData)
	*tData\thread_sql_abfrage=sql_abfrage$
	*tData\thread_dateipfad=dateipfad$
	*tData\thread_dateiname=dateiname$
	*tData\thread_ziel_verzeichnis=ziel_verzeichnis$
	Thread(*tData)
	
EndIf
CloseFile(0) 
Du solltest dir Gedanken über einen Threadpool machen. Am Anfang werden n Threads erstellt und diese warten darauf Aufgaben zu erledigen. Das kann man mit einer ConcurrentQueue erledigen. Das Hauptprogramm schiebt Aufgaben in die Queue und der Thread, der gerade nichts zu tun hat, nimmt sich die Aufgabe und arbeitet sie ab. Darf die Aufgabe selbst nicht parallelisiert ausgeführt werden, darfst du eben nur einen Thread verwenden.
Bezüglich der ConcurrentQueue hab ich mal ein Video gemacht. Vielleicht hilft es dir weiter: [PB] HowTo: ConcurrentQueue
Paddy1988
Beiträge: 19
Registriert: 28.12.2015 15:31

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von Paddy1988 »

Der einzige Grund warum ich einen Thread erstellen muss ist das sich das Programm nicht aufhängt, die Datenbankabfrage dauert evtl. ein paar Minuten.
Da in dieser Zeit sich Windows meldet und sagt 'keine Rückmeldung' zeigt, sollte der Teil mit der Datenbankabfrage ausgelagert werden, sodass die Windows kein Fehler schmeißt.
Es ist demnach so gewollt das ich auf den Thread warte bis dieser abgearbeitet ist, weil dann wurde die Datenbankabfrage gesendet und die Datei erzeugt (aus den Daten der Datenbankabfrage). Danach wird die nächste Datei eingelesen, die Datenbankabfrage gesendet und die Datei aus den Daten der Abfrage erzeugt, und immer so weiter bis keine Dateien mehr eingelesen werden.
Benutzeravatar
NicTheQuick
Ein Admin
Beiträge: 8809
Registriert: 29.08.2004 20:20
Computerausstattung: Ryzen 7 5800X, 64 GB DDR4-3200
Ubuntu 24.04.2 LTS
GeForce RTX 3080 Ti
Wohnort: Saarbrücken

Re: Thread erstellt und dennoch ungültiger Speicherzugriff

Beitrag von NicTheQuick »

Aber wenn du auf Beendigung des Threads wartest, hängt dein Hauptprogramm ja trotzdem bei dem 'WaitThread()'. Von daher macht das Vorgehen so keinen Sinn.
Antworten