Laden...

Cross Thread operation not valif within STA

Erstellt von Tol3l3e vor 3 Jahren Letzter Beitrag vor 3 Jahren 905 Views
T
Tol3l3e Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren
Cross Thread operation not valif within STA

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.

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

4.931 Beiträge seit 2008
vor 3 Jahren

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.

T
Tol3l3e Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren

Moin,

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.

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 X(

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

Trotzdem danke für die Tipps 👍

P.S

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

4.931 Beiträge seit 2008
vor 3 Jahren

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":

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?

T
Tol3l3e Themenstarter:in
3 Beiträge seit 2020
vor 3 Jahren

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/mdm/109773506?c=128474251915&lc=de-WW