Hallo Zusammen,

ich versuche mich gerade daran Aufgaben in verschiedenen Threads bearbeiten zu lassen, um die Zenon Runtime nicht zu blockieren.

Hintergrund ist folgender, ich habe eine Funktion die mir einen Report (von einem Energiezähler) als PDF exportiert.
Da ich nun etwas 400 Zähler habe und nur von bestimmten einen Report möchte (ca.40 bis jetzt Tendenz steigend), dachte ich ein AddIn könnte hilfreich sein.
Es soll einfach die Verknüpften Variablen ersetzen und die Funktion ausführen.
Die Idee ist am Anfang eine Variable vom Typ list zu erstellen. Dann müsste ich wenn ein Zähler neu exportiert werden soll den Index der Zählervariablen als neues Element der Liste anlegen.
Danach führt das Programm die Exportfunktion für jeden Listeneintrag durch.
Soweit so gut. Das Problem die Export Funktion benötigt ein paar Sekunden um das PDF zu erstellen.
Das Programm rattert alle Zähler durch, verändert die Variablen und startet die Funktion schneller hintereinander als Sie ausgeführt werden kann.

Da dachte ich mit Thread.Sleep oder Thread.Task.Delay().Wait etc. könnte nach jedem Schleifendurchlauf ein paar Sekunden warten. Dadurch friert aber die Runtime ein, und die Funktion wird erst nicht ausgeführt.

So komme ich zum MultiThreading

Das AddIn soll einen weiteren Thread außerhalb des MainThread erstellen, Sub_Thread_1 hier werden die Variablen gesetzt und gewartet bis die RT Funktion welche dann in einem dritten Thread Sub_Thread.2 gestartet wird fertig ist.

Die Thread's starten und tun ihre Arbeit auch soweit, aber sobald ich eine Verzögerung in Sub_Thread_1 einbaue Thread.Sleep oder Thread.Task.Delay().Wait oder auch nur eine lange While Schleife, bricht dieser ab. Es kommt lediglich die Fehlermeldung: Der Thread wurde abgebrochen.

Hier mal ein bisschen Code, mit dem ich das ganze jetzt schon ne weile teste:

Code:

 public class ProjectWizardExtension : IProjectWizardExtension
    {
        #region IProjectWizardExtension implementation


        public void Run(IProject context, IBehavior behavior)
        {
            try
            {


                //###############################################################################################
                //Liste der Zähler Index, welche exportiert werden sollen, weitere Zähler bitte hier eintragen...
                List Index = new List();
                //#0
                Index.Add("140");
                //#1
                Index.Add("325");
                //#2
                Index.Add("120");
                //###############################################################################################
                Scada.AddIn.Contracts.Function.IFunction obFctTrend;
                //RT Funktion welche bearbeitet wird
                obFctTrend = context.FunctionCollection["FU_Export_Report"];


                for (int i = 0; i <= Index.Count - 1; i++)
                {
                    //Ersetzen des Index der verknüpften Variablen in der Funktion auf den Index des aktuellen Zähler
                    //obFctTrend.SetDynamicProperty("Filter[0].DataSet[0].Filter[0].VarInfo[0].Variable", ....


                }
                //RT Funktion in eigenem Thread ausführen
                Thread thread = new Thread(RunThread_1);
                thread.Start(context);
            }
            catch (Exception err)
            {
                context.ChronologicalEventList.AddEventEntry("Fehler: " + err.Message);
            }
        }
        
        #endregion
        private void RunThread_1(Object ob)
        {
            IProject context = (IProject)ob;
            try
            {
                Thread thread = new Thread(RunThread_2);
                thread.Start(context);
                Task.Delay(5000).Wait();
                context.ChronologicalEventList.AddEventEntry("Sub Thread 1 Ende");
            }
            catch (Exception err)
            {
                context.ChronologicalEventList.AddEventEntry("Fehler RunThread_1: " + err.Message);
            }
        }


        private void RunThread_2(Object ob)
        {
            IProject context = (IProject)ob;
            try
            {
                context.ChronologicalEventList.AddEventEntry("Sub Thread 2 Ende");
            }
            catch (Exception err)
            {
                context.ChronologicalEventList.AddEventEntry("Fehler RunThread_2: " + err.Message);
            }
        }
    }
}
Ist die Lebenszeit des Sub Thread irgendwie begrenzt???
Ich habe mich mit dem Thema vorher noch nie beschäftigt, aber ich finde hier im Forum sehr wenig dazu, und was ich unter
github: https://github.com/copa-data gefunden habe, habe ich verwendet um den Code zu erstellen.

Vielleicht kann mir jemand die richtige Richtung zeigen....

Gruß Tobias