Folgendes vereinfachtes (!) Szenario: (auch als VS 2010-Projekt hier angefügt)
Es gibt eine Form1, auf dieser befindet sich eine ListBox1 und ein Button1. Dann folgender Code:
Natürlich erscheint jetzt der Fehler:
Das will ich aber nicht. Warum? Ich möchte die Klasse anderen zur Verfügung stellen und die sollen keine Probleme mit Deleganten & Co bekommen. Das Problem soll also in der Klasse "Arbeiter" gelöst werden. Nur wie? Threads sind für mich ein wenig Neuland. Mit dem Backgroundworker bekomm ich das ganze auf die Reihe, allerdings kann ich den für meine richtige Klasse nicht mehr nehmen. Hat jemand eine Idee? Evtl. beim Aufgruf von "New" sich merken, von welchem Thread das Objekt erzeugt wurde und bei "RaiseEvent" irgendwie diesen gemerkten Thread wieder benutzen? Wäre für jeden Tipp dankbar, muss auch kein ganzer Lösungsweg sein!
Es gibt eine Form1, auf dieser befindet sich eine ListBox1 und ein Button1. Dann folgender Code:
VB.NET-Quellcode
- Public Class Form1
- ' In diesem Code sollte keine Thread-Behandlung durchgeführt werden.
- ' Mir wäre es am liebsten, wenn ich den unten stehenden Code so stehen lassen könnte.
- Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
- Dim meinArbeiter As New Arbeiter
- AddHandler meinArbeiter.ZwischenergebnisEingetroffen, AddressOf meinArbeiter_ZwischenergebnisEingetroffen
- End Sub
- Private Sub meinArbeiter_ZwischenergebnisEingetroffen(ByRef sender As Arbeiter, ByVal ergebnis As String)
- ListBox1.Items.Add("Objekt Nr. " & sender.objektID.ToString & " hat Event gefeuert bei " & ergebnis.ToString & ".")
- End Sub
- End Class
VB.NET-Quellcode
- Public Class Arbeiter
- ' Hier sollte die Threadbehandlung laufen. Ich weiss allerdings nicht, wie ich den Code dahingehend ändere.
- Public Event ZwischenergebnisEingetroffen(ByRef sender As Arbeiter, ByVal ergebnis As String)
- Private erstellteObjekte As Integer
- Public objektID As Integer
- Public Sub New()
- objektID = erstellteObjekte 'Diesem Objekt eine ID geben
- erstellteObjekte += 1 'Den Counter erhöhen, weil es jetzt ein neues Objekt von mir gibt
- Dim Thread As New Threading.Thread(AddressOf Rechne)
- Thread.Start()
- End Sub
- Public Sub Rechne()
- Dim i As Integer
- Do While i < 2147483646 'Datentyp Integer geht höchstens bis 2147483647
- i += 1
- If i Mod 10000 = 0 Then
- RaiseEvent ZwischenergebnisEingetroffen(Me, i) 'Immer, wenn i genau durch 10000 teilbar ist, Event feuern
- End If
- Loop
- End Sub
- End Class
Natürlich erscheint jetzt der Fehler:
...und natürlich könnte ich diesen Fehler beheben, indem ich das in dem Quellcode der Form1 wie folgt mache:Ungültiger threadübergreifender Vorgang: Der Zugriff auf das Steuerelement ListBox1 erfolgte von einem anderen Thread als dem Thread, für den es erstellt wurde.
Das will ich aber nicht. Warum? Ich möchte die Klasse anderen zur Verfügung stellen und die sollen keine Probleme mit Deleganten & Co bekommen. Das Problem soll also in der Klasse "Arbeiter" gelöst werden. Nur wie? Threads sind für mich ein wenig Neuland. Mit dem Backgroundworker bekomm ich das ganze auf die Reihe, allerdings kann ich den für meine richtige Klasse nicht mehr nehmen. Hat jemand eine Idee? Evtl. beim Aufgruf von "New" sich merken, von welchem Thread das Objekt erzeugt wurde und bei "RaiseEvent" irgendwie diesen gemerkten Thread wieder benutzen? Wäre für jeden Tipp dankbar, muss auch kein ganzer Lösungsweg sein!