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 » Basistechnologien und allgemeine .NET-Klassen » Cross Thread operation not valif within STA
Letzter Beitrag | Erster ungelesener Beitrag Druckvorschau | Thema zu Favoriten hinzufügen

Antwort erstellen
Zum Ende der Seite springen  

Cross Thread operation not valif within STA

 
Autor
Beitrag « Vorheriges Thema | Nächstes Thema »
Tol3l3e
myCSharp.de-Mitglied

Dabei seit: 28.07.2020
Beiträge: 3


Tol3l3e ist offline

Cross Thread operation not valif within STA

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

Moin,

für eine dll möchte ich ein automatisches Speicher eines Projektes nach 10 Minuten verwirklichen. Das Auslösen des Timers plus EventHandle funktioniert auch. Nur das Speichern führt zu einer Exception, da ich scheinbar einen neuen Thread generiert habe bzw. benutzen.
Wie könnte man das am geschicktesten umgehen. Alle meine Anfänger/Google Tricks haben leider nichts gebracht.

C#-Code:
using System;
using System.Collections.Generic;
using System.Globalization;
using Siemens.Engineering;
using Siemens.Engineering.AddIn.Menu;
using System.Linq;
using System.Timers;
using System.Threading;
using System.Windows.Forms;
using System.ComponentModel;

namespace AddInExample
{
    public class AddIn : ContextMenuAddIn
    {
        private readonly TiaPortal _tiaPortal;
        private readonly Settings _settings;


        public AddIn(TiaPortal tiaPortal) : base("Automatisches Speichern nach 10min")
        {
            _tiaPortal = tiaPortal;
            _settings = Settings.Load();


            System.Timers.Timer myTimer = new System.Timers.Timer(5000);
            myTimer.Elapsed += myTimer_Elapsed;
            myTimer.Enabled = true;
            myTimer.AutoReset = true;
        }

        private void myTimer_Elapsed(Object myObject,
                                            EventArgs myEventArgs)
        {
            try
            {
                Project project = null;
                project = _tiaPortal.Projects.First(projects => projects.IsPrimary);
                project.Save();

            }
            catch (Exception ex)
            {
                using (Form owner = Util.GetForegroundWindow())
                {
                    MessageBox.Show(owner, ex.ToString(), "FEHLER");
                }
            }
        }
}

Danke im Voraus schon mal für jede Hilfe

Tol3l3e hat dieses Bild (verkleinerte Version) angehängt:
Anmerkung 2020-07-28 163046.jpg
Volle Bildgröße

28.07.2020 16:34 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


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


Th69 ist offline

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

Hallo und willkommen,

System.Timers.Timer verwendet intern einen eigenen Thread.
Für WinForms gibt es den System.Windows.Forms.Timer, so daß dann der UI-Thread benutzt wird.

Alternativ s.  [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).

PS: Bisher benutzt du den Timer als lokale Variable, d.h. der GC wird diesen dann womöglich wegräumen - lege ihn besser als Member an.
28.07.2020 17:03 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Tol3l3e
myCSharp.de-Mitglied

Dabei seit: 28.07.2020
Beiträge: 3

Themenstarter Thema begonnen von Tol3l3e

Tol3l3e ist offline

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

Moin,

Zitat:
Für WinForms gibt es den System.Windows.Forms.Timer, so daß dann der UI-Thread benutzt wird.

Das ist bei mir leider nicht möglich, da ich kein UI benutze.

Zitat:
Alternativ s. [FAQ] Controls von Thread aktualisieren lassen (Control.Invoke/Dispatcher.Invoke).

Da hab ich immer die gleichen Probleme mit. Die selbe Fehlermeldung wird dann immer wieder generiert, da ich ja meine Timer Funktion in einen anderen Thread ausglieder. Thread.Sleep bringt leider auch nichts, da dann das Hauptprogramm mit einfriert enttäuscht


So langsamen gehen damit mir und dem Internet die Ideen aus. Überleg schon fast die Stopwatch zu benutzen Teufel


Trotzdem danke für die Tipps Daumen hoch

P.S

Zitat:
PS: Bisher benutzt du den Timer als lokale Variable, d.h. der GC wird diesen dann womöglich wegräumen - lege ihn besser als Member an.

Ist mir bekannt, war nur am rumspielen
30.07.2020 08:08 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Th69
myCSharp.de-Poweruser/ Experte

avatar-2578.jpg


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


Th69 ist offline

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

Um was für einen Projekttyp handelt es sich denn?
Hast du evtl. einen  SynchronizationContext (von der TiaPortal-Schnittstelle) zur Verfügung?

In  TIAPortalOpennessenUS_en-US.pdf steht in "2.2 Major changes in TIA Portal Openness V15.1":

Zitat:
Cross-thread operations

Access to Openness objects is not inherently thread-safe.If you use multi-threading to improve the performance of your Openness application, it is recommended to create your TiaPortal instance with an MTA. If TiaPortal is created or attached within an STA thread, all Openness objects associated with that Portal instance should be accessed from the same STA thread; otherwise, an exception will be thrown.

Vllt. hilft dir das weiter?
30.07.2020 08:37 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Tol3l3e
myCSharp.de-Mitglied

Dabei seit: 28.07.2020
Beiträge: 3

Themenstarter Thema begonnen von Tol3l3e

Tol3l3e ist offline

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

Moin,

ich glaub ich muss ein bisschen ausholen.

Es gibt in der Version 16 vom Engineering Tool TIA die Möglichkeit sogenante Add-Ins (eigentlich .dlls die von einem Converter in .addIn umgewandelt werden) zu integrieren. Da es seit Jahren noch immer nicht die Möglichkeit gibt, ein automatisches Speichern nach Zeit x durchführen zu lassen, dachte ich, programmier dir das doch selber.

Das Add-In Konzept baut auf TIA Openness auf, wird aber Eventgesteuert ausgeführt, scheinbar. Ein Thread.Sleep sorgte für das Einfrieren von TIA. Das Add-In wird also aus TIA selbst gestartet. Muss dann das ganze Add-In alse ein neuer Thread/Task bekannt gegeben werden?

Für bessere Verständnis hier dann mal die ganze Dokumentation für die Add-In

 https://support.industry.siemens.com/cs/...251915&lc=de-WW
30.07.2020 09:59 E-Mail | Beiträge des Benutzers | zu Buddylist hinzufügen
Baumstruktur | Brettstruktur       | Top 
myCSharp.de | Forum Der Startbeitrag ist älter als 5 Monate.
Der letzte Beitrag ist älter als 5 Monate.
Antwort erstellen


© Copyright 2003-2021 myCSharp.de-Team | Impressum | Datenschutz | Alle Rechte vorbehalten. | Dieses Portal verwendet zum korrekten Betrieb Cookies. 17.01.2021 23:27