vb@rchiv
VB Classic
VB.NET
ADO.NET
VBA
C#
SEPA-Dateien erstellen inkl. IBAN-, BLZ-/Kontonummernprüfung  
 vb@rchiv Quick-Search: Suche startenErweiterte Suche starten   Impressum  | Datenschutz  | vb@rchiv CD Vol.6  | Shop Copyright ©2000-2024
 
zurück

 Sie sind aktuell nicht angemeldet.Funktionen: Einloggen  |  Neu registrieren  |  Suchen

VB.NET - Fortgeschrittene
Re: Der Zugriff auf das Steuerelement xy erfolgte von einem andere Thread... 
Autor: Manfred X
Datum: 26.02.20 06:16

Hallo!

Du scheinst - vielleicht ohne es zu wissen - in eine Multithreading-Umgebung geraten zu sein.
Ich vermute, der SPS-Datenlieferant läuft in einem eigenen Thread und ruft Ereignisse Deiner
Oberfläche auf, in denen Du auf Eigenschaften Deiner Controls zugreifen willst.

Deine Angaben sind zu allgemein, um konkrete Hinweise geben zu können, deshalb hier ein
kleines Beispiels zur Verdeutlichung des möglichen Lösungsweges:

In dem WinForms-Formular soll eine Uhr mitlaufen. Dafür gibt es die Routine "MyClock".
Die legt den Thread stets 5 Sekunden schlafen und meldet danach die aktuelle Zeit an
die Ereignisroutine "GetTime". Damit während des Schlafs der Routine der Hauptthread nicht
blockiert wird, läuft 'MyClock' als Hintergrundprozess "GetTimeThread".
Beweis: Du kannst in der Textbox jederzeit Zeichen eintragen oder löschen. Die Oberfläche
ist also nicht blockiert.

Allerdings: Wenn Du in der Ereignisroutine direkt auf Eigenschaften Deiner Controls zugreifen
willst, kommt die bekannte Fehlermeldung. "GetTimeThread" kennt Deine Controls nicht.

Aus diesem Grund benötigst Du den Delegaten "StringIntegerDelegate", der einem Thread bekannt
machen kann, dass eine SUB mit String und Integer-Parameter gerufen wird und dessen Instanz (New)
jeweils angibt, wo diese SUB im Speicher zu finden ist. Diese Informationen plus die
erforderlichen Parameterwerte packst Du in einen Invoke-Aufruf, der die Weiterleitung erledigt.

Ein entsprechendes Vorgehen könnte Dein Problem lösen.

WinForms:
Public Class frmDemo
 
    Dim lblTime As New Label With
        {.Parent = Me, .Width = 100, .Left = 10, .Top = 10}
 
    Dim txtEdit As New TextBox With
        {.Parent = Me, .Width = 100, .Left = 10, .Top = 40, .Height = 150, 
         .Multiline = True}
 
    'Ereignis, dem die aktuelle Uhrzeit gemeldet wird
    Private Event GetTime(ByVal hhmmss As String, ByVal counter As Integer)
 
    'Ein Delegat, der eine Sub incl. eines Parameter des Typs String 
    'und einen zweiten des Typs Integer ansprechen kann
    Delegate Sub StringIntegerDelegate(ByVal str As String, int As Integer)
 
 
 
    Private Sub frmDemo_Load(sender As Object, e As EventArgs) Handles _
      MyBase.Load
 
        'Start der Routine MyClock als Hintergrundprozess
        'Das Formular bleibt verfügbar, während MyClock schläft ... 
        Dim GetTimeThread As New Threading.Thread(AddressOf MyClock)
        GetTimeThread.Start()
    End Sub
 
 
    Private Sub MyClock()
        'Eine Routine, die den Thread 5 sek schlafen legt und dann die 
        'aktuelle Zeit per Ereignisaufruf meldet
        Do
            Static i As Integer
 
            i += 1
            If i > 10000 Then i = 0
 
            Threading.Thread.Sleep(5000)
            RaiseEvent GetTime(Now.ToLongTimeString, i)
        Loop
    End Sub
 
 
    Private Sub frmDemo_GetTime(hhmm As String, counter As Integer) Handles _
      Me.GetTime
        'Der Ereignishandler wird aus dem Thread GetTimeThread gerufen 
 
        'Hier kommt der Fehler: Ungültiger Threadübergreifender Vorgang
        'Der Zugriff auf das Control lblTime erfolgt nicht aus dem Haupthread 
        'lblTime.Text = hhmm
 
        'Auf das Control wird per Invoke zugegriffen. Dafür benötigt man eine 
        'Routine (Showtime), deren Parametertyp (per Delegate) und deren 
        'Speicher-Adresse (AddressOf ...) dem 'blinden' Hintergrundthread 
        'zunächst bekannt gemacht werden müssen
        lblTime.Invoke(New StringIntegerDelegate(AddressOf ShowTime), hhmm, _
          counter)
    End Sub
 
 
    Private Sub ShowTime(ByVal hhmm As String, counter As Integer)
        'Hilfsroutine zum Setzen der Controls-Eigenschaft
        lblTime.Text = hhmm & " - " & counter.ToString
        lblTime.Refresh()
    End Sub
 
End Class


Beitrag wurde zuletzt am 26.02.20 um 06:18:00 editiert.
alle Nachrichten anzeigenGesamtübersicht  |  Zum Thema  |  Suchen

 ThemaViews  AutorDatum
Der Zugriff auf das Steuerelement xy erfolgte von einem ande...668Parallax25.02.20 15:51
Re: Der Zugriff auf das Steuerelement xy erfolgte von einem ...340Manfred X26.02.20 06:16
Re: Der Zugriff auf das Steuerelement xy erfolgte von einem ...319Parallax26.02.20 16:36

Sie sind nicht angemeldet!
Um auf diesen Beitrag zu antworten oder neue Beiträge schreiben zu können, müssen Sie sich zunächst anmelden.

Einloggen  |  Neu registrieren

Funktionen:  Zum Thema  |  GesamtübersichtSuchen 

nach obenzurück
 
   

Copyright ©2000-2024 vb@rchiv Dieter Otter
Alle Rechte vorbehalten.
Microsoft, Windows und Visual Basic sind entweder eingetragene Marken oder Marken der Microsoft Corporation in den USA und/oder anderen Ländern. Weitere auf dieser Homepage aufgeführten Produkt- und Firmennamen können geschützte Marken ihrer jeweiligen Inhaber sein.

Diese Seiten wurden optimiert für eine Bildschirmauflösung von mind. 1280x1024 Pixel