none
Problem beim Multihreading RRS feed

  • Frage

  • Hallo Zusammen,

    ich  versuch grade mit einem eigenen Thread auf eine Datenbank (Cache) zuzugreifen, da hier Datenbankseitig eine Funktion ausgeführt wird, die ca. 1,5 Minuten dauert.

    Mein Problem ist jetzt, dass trotz eigenem Thread, die ganze Form hängt.

    Ich hab schon Probiert, es in ein UserControll auszulagern, in der Hoffnung, dass dann nur das Controll hängt, hat aber auch nicht funktioniert.

    Dann habe ich es noch mit einen Aufruf als Delegate versucht, was leider auch nicht geklappt hat.

    Hier erstmal der Aufruf als Thread im UserControl

    'Klasse die den Datenbankzugriff kapselt 
    
    Private objLaden As New LadeMethode
    
    'Erzeugen eines neuen Thread, der die Daten aus der Datenbank laden soll
    
    Private FileSaverThread As New Thread(AddressOf objLaden.Lade) 
    
    
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
    'Starten des Thread 
    
    FileSaverThread.IsBackground = True 
    
    FileSaverThread.Priority = ThreadPriority.Normal FileSaverThread.Start()
    
    End Sub

    Hier der Aufruf als Delegate:

    Public Class Form1 
    
    'Deklaration des Delegate 
    
    Private Delegate Function test() As Boolean
    
    
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
    
    
    'Objekt was den Datenbank zugriff kapselt 
    
    Dim objLoad As New TestThread.LadeMethode 
    
    Dim delTest As test
    
    'Erzeugen und ausführen des Delegaten 
    
    delTest = New test(AddressOf objLoad.Lade)
    
    delTest.BeginInvoke(AddressOf Oncallback, Nothing )
    
    End Sub 
    
    
    Private Sub Oncallback(ByVal asynresult A IAsyncResult)
    
    Dim result As Integer = 0
    
    Dim obj As AsyncResult = CType (asynresult, AsyncResult) 
    
    Dim c As test = CType (obj.AsyncDelegate, test) 
    
    result = c.EndInvoke(asynresult)
    
    MessageBox.Show(result.ToString)
    
    End Sub 
    
    
    End Class

     

    Wie man sieht hab ich in beiden Beispielen auch schon ein paar Sachen ausprobiert, hat aber alles nichts geholfen.

    Nun hat vielleicht einer eine Ahnung woran es liegen kann, das es mit dem Thread nicht Funktioniert und wie ich vielleicht das Problem lösen kann.

    Danke schon mal.

    Freitag, 14. Mai 2010 10:11

Antworten

  • Hallo Palin,

    nimms mir nicht übel, aber Dein Code ist nur schwer genießbar ;-)
    und nachvollziehen, was Du dort überhaupt anstellst, kann leider nicht.

    Für Windows Steuerelemente gilt (seien sie in .NET oder in VB Classic geschrieben),
    dass ausschließlich auf dem Thread aufgerufen werden sollten, der sie erzeugt hat.
    Alles andere führt zu Seiteneffekten bzw. .NET wirft gleich eine Ausnahme.

    Zunächst solltest Du Dir mal den BackgroundWorker anschauen,
    der vieles kapselt, was beim Formularzugriff zu beachten ist.

    Und Deinen Code so umstellen, dass der FileSaver (oder Lader?) seine Parameter
    und Ergebnisse unabhängig von den Formulardaten verwaltet/abliefert.
    Übergebe erforderliche Parameter beim Start - dafür ist der Parameter
    beim Threadstart oder auch BackgroundWorker gedacht.
    Und liefere die Ergebnisse an das empfangende Steuerelement beim
    BackgroundWorker im ProgressChanged oder Completed (via UserState) ab.

    Gruß Elmar

    Freitag, 14. Mai 2010 15:41
    Beantworter

Alle Antworten

  • Hallo noch mal Zusammen,

    ich hab mitbekommen, dass ich beim Datenbank zugriff auf eine VB6 Klasse zugreife.

    Diese scheint nicht Multithread Fähig zu sein.

    Mein Workaround ist, einfach vorher einen andern Thread zu starten, der ein neues Form mit einen ProgressBar erzeugt und den ProgressBar einfach durchlaufen läst, bis der andere „Thread“ mit dem Laden der Daten fertig ist.

    Unschön ist hier leider noch, dass wenn ich versuche die Form zu verschieben, sie wieder hängt auch der ProgressBar.  Wenn ich in der Schleife, für den ProgressBar, ein Show für seine Form aufrufe, bekomme ich eine neue Form in der ein ProgressBar läuft.

    Die ich aber nicht verschieben kann, die alte kann ich zwar noch verschieben aber in ihr läuft der ProgressBar nicht.

    Ist auf jeden fall schon mal besser, als wenn die Form gar nichts macht.

    Falls einer eine Idee hat wie, ich es besser machen kann würde ich mich freuen.

    Sonst Probiere ich erst mal weiter vielleicht finde ich ja noch was.

    Mit freundlichen Grüßen

    Palin
    Freitag, 14. Mai 2010 14:40
  • Hallo Palin,

    nimms mir nicht übel, aber Dein Code ist nur schwer genießbar ;-)
    und nachvollziehen, was Du dort überhaupt anstellst, kann leider nicht.

    Für Windows Steuerelemente gilt (seien sie in .NET oder in VB Classic geschrieben),
    dass ausschließlich auf dem Thread aufgerufen werden sollten, der sie erzeugt hat.
    Alles andere führt zu Seiteneffekten bzw. .NET wirft gleich eine Ausnahme.

    Zunächst solltest Du Dir mal den BackgroundWorker anschauen,
    der vieles kapselt, was beim Formularzugriff zu beachten ist.

    Und Deinen Code so umstellen, dass der FileSaver (oder Lader?) seine Parameter
    und Ergebnisse unabhängig von den Formulardaten verwaltet/abliefert.
    Übergebe erforderliche Parameter beim Start - dafür ist der Parameter
    beim Threadstart oder auch BackgroundWorker gedacht.
    Und liefere die Ergebnisse an das empfangende Steuerelement beim
    BackgroundWorker im ProgressChanged oder Completed (via UserState) ab.

    Gruß Elmar

    Freitag, 14. Mai 2010 15:41
    Beantworter