myCSharp.de - DIE C# und .NET Community
Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 
 | Suche | FAQ

» Hauptmenü
myCSharp.de
» Startseite
» Forum
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Suche
» Regeln
» Wie poste ich richtig?
» Forum-FAQ

Mitglieder
» Liste / Suche
» Wer ist wo online?

Ressourcen
» openbook: Visual C#
» openbook: OO
» Microsoft Docs

Team
» Kontakt
» Übersicht
» Wir über uns

» myCSharp.de Diskussionsforum
Du befindest Dich hier: Community-Index » Diskussionsforum » Entwicklung » Grundlagen von C# » Threadübergreifender Zugriff auf ein Objekt schlägt fehl
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Threadübergreifender Zugriff auf ein Objekt schlägt fehl

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
chhoelzle chhoelzle ist männlich
myCSharp.de-Mitglied

Dabei seit: 05.11.2018
Beiträge: 2


chhoelzle ist offline

Threadübergreifender Zugriff auf ein Objekt schlägt fehl

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo
Ich habe folgende Klasse

C#-Code:
using BFH.Model;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace BFH.CustomControls
{
    /// <summary>
    /// Interaktionslogik für SafetyStatus.xaml
    /// </summary>
    public partial class SafetyStatusView : Window
    {
        private SafetyStatus SafetyStatus;
        private TextBlock[] TextBlocks;
        public Border[] Borders;

        public SafetyStatusView()
        {
            InitializeComponent();

            SafetyStatus = new SafetyStatus();
            SafetyStatus.PropertyChanged += new PropertyChangedEventHandler(SafetyStatusPropertyChanged);

            TextBlocks = new TextBlock[SafetyStatus.Status.Count];
            Borders = new Border[SafetyStatus.Status.Count];

            BuildGUIContent();

        }

        #region methods
        private void BuildGUIContent()
        {
            for (int i = 0; i < SafetyStatus.Status.Count; i++)
            {
                Grid.RowDefinitions.Add(new RowDefinition());

                TextBlocks[i] = new TextBlock();
                Borders[i] = new Border();

                Grid.Children.Add(TextBlocks[i]);
                Grid.Children.Add(Borders[i]);

                Grid.SetRow(TextBlocks[i], i);

                Grid.SetRow(Borders[i], i);
                Grid.SetColumn(Borders[i], 1);

                TextBlocks[i].Text = SafetyStatus.Text[i];
                TextBlocks[i].FontFamily = new FontFamily("Segoe UI Semibold");
                TextBlocks[i].FontSize = 16;
                TextBlocks[i].Foreground = Brushes.White;
                TextBlocks[i].SetValue(TextBlock.MarginProperty, new Thickness(2));

                if (ConnectPLC.Read_BOOL_fromPLC(SafetyStatus.SignalNames[i],true))
                    Borders[i].Background = Brushes.Green;
                else
                    Borders[i].Background = (SolidColorBrush)(new BrushConverter().ConvertFrom("#1C536F"));

                Borders[i].SetValue(Border.CornerRadiusProperty, new CornerRadius(10));
                Borders[i].SetValue(Border.MarginProperty, new Thickness(2));
            }
        }

        private void SafetyStatusPropertyChanged(object sender, PropertyChangedEventArgs e)
        {
            for (int i = 0; i < SafetyStatus.Status.Count; i++)
            {
                if (SafetyStatus.Status[i])
                    try
                    {
                        Borders[i].Background = Brushes.Green;
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show(err.ToString());
                    }
                else
                    try
                    {
                    Borders[i].Background = (SolidColorBrush)(new BrushConverter().ConvertFrom("#1C536F"));
                    }
                    catch (Exception err)
                    {
                        MessageBox.Show(err.ToString());
                    }
            }
        }
        #endregion
    }
}

Wenn der Eventhandler die SafetyStatusPropertyChanged Funktion aufruft und die Borders[i].Background beschreiben sollte, tritt folgender Fehler auf:

Fehlermeldung:
System.InvalidOperationExeption: Der aufrufende Thread kann nicht auf dieses Objekt zugreifen, da sich das Objekt im Besitz eines anderen Threads befindet ....

Wie kann ich dies Thread übergreifend zuweisen?
07.11.2018 10:44 Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


Dabei seit: 01.04.2008
Beiträge: 3.406
Entwicklungsumgebung: Visual Studio 2015/17


Th69 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo,

verwendest du denn eigene Threads (oder Tasks) in der Klasse SafetyStatus?

Schau in  [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).

PS: Editiere deinen Beitrag und füge die Code (C#)-Tags hinzu.
07.11.2018 11:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Coffeebean Coffeebean ist männlich
myCSharp.de-Team

avatar-3295.gif


Dabei seit: 25.08.2011
Beiträge: 2.187
Entwicklungsumgebung: VS 2005-2017, VS Code
Herkunft: Deutschland/Schweiz


Coffeebean ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hallo chhoelzle,

 [Hinweis] Wie poste ich richtig? Bitte benutze Code-Tags.

Gruss

Coffeebean
07.11.2018 11:20 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
chhoelzle chhoelzle ist männlich
myCSharp.de-Mitglied

Dabei seit: 05.11.2018
Beiträge: 2

Themenstarter Thema begonnen von chhoelzle

chhoelzle ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Eigentlich brauche ich nach meiner Meinung keinen eigenen Thread

Das einzige ist der PropertyChangedEventHandler, mit welchem ich die Funktion benötige, gibt wohl einen eigenen Thread, nehme ich an.
07.11.2018 14:41 Beiträge des Benutzers | zu Buddylist hinzufügen
Taipi88 Taipi88 ist männlich
myCSharp.de-Mitglied

avatar-3220.jpg


Dabei seit: 02.02.2010
Beiträge: 989
Entwicklungsumgebung: VS 2010
Herkunft: Mainz


Taipi88 ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Hi,

was aus dem bereits verlinkten Artikel für dich hätte hervorgehen sollen:

Du hast offensichtlich neben deinem GUI-Thread wohl mindestens einen 2. Thread - und da du aus diesem 2. Thread heraus die GUI änderst - wirft er dir zu Recht einen Fehler um die Ohren. Wie man das korrigiert - ist im Artikel beschrieben.

LG
07.11.2018 15:00 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Abt
myCSharp.de-Team

avatar-4119.png


Dabei seit: 20.07.2008
Beiträge: 13.251
Herkunft: Stuttgart/Stockholm


Abt ist offline

Beitrag: beantworten | zitieren | editieren | melden/löschen       | Top

Puh, also der Code ist deutlich verbesserungswürdig (besonders die Namespaces, Struktur, Namings und  [Artikel] Drei-Schichten-Architektur )

Letzten Endes sieht der Code danach aus, dass der Event in SafetyStatus in einem anderen Thread läuft.
Das erklärt auch den Fehler.

Da für uns SafetyStatus nicht ersichtlich ist, solltest Du Dir die Doku oder dessen Code anschauen.
Letzten Endes ist aber wie gesagt auch  [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke) die Lösung - egal was in SafetyStatus steckt.
07.11.2018 21:21 Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als ein Jahr.
Der letzte Beitrag ist älter als ein Jahr.
Antwort erstellen


© Copyright 2003-2019 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 12.12.2019 01:42