Probleme mit Daten auslesen



  • Hallo, ich bekomme daten nur aus der
    "System.IO.MemoryMappedFiles"
    wenn ich die einzelnen Zeilen mit Breakpoints setze.
    Wenn das Programm nur durchläucht, ist die Konsole leer.

    Es lieg tnicht daran, dass das Programm schon durchgelaufen wird, da ich eine ENdlos Whileschleife verwende.

    DIe MemoryMapped Methode, die ich geschrieben habe befindet sich in einer eigenen Klasse der .sln (weiß nicht in iwie fern das eventuel helfen könnte)
    lg



  • Vermutlich benutzt du MemoryMappedFile falsch.

    Zeig ein Minimalbeispiel des Codes, das das Problem reproduziert.



  • Klasse mit Memory mapped File (STRUCT auf variable port reduziert):

    unsafe public struct DataExchangeEmailInTmp
            {
                public Int16 port;
            }
    
            unsafe public DataExchangeIn Mem()
            {
                DataExchangeEmailInTmp dataExchangeReadTmp;
                DataExchangeIn dataExchangeRead;
    
                // init
                dataExchangeRead.eMailIn.port = 0;
    
                // get size
                int dataSIze = Marshal.SizeOf(typeof(DataExchangeEmailInTmp));
    
                // Open a mapped file with read access and one with write access. 
                //  using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
                using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
                using (var accessorRead = mmfRead.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Read))
    
                // Read the structure
                accessorRead.Read(0, out dataExchangeReadTmp);
    
                return dataExchangeRead; // STRUCT Mit STrings anstelle char[255]                   
            } 
        }
    

    AUFRUF:

    static void Main(string[] args)
            {
    
                while (true)
                {
                    Thread.Sleep(100);
    
                    //Read Data from Shared Memory
                    SharedMemoryRead ShareMemRd = new SharedMemoryRead();
                    GVL.SmIn = ShareMemRd.Mem();
                }
            }
    

    Die Daten passen soweit (jedenfalls wenn ich breakpoints setze)..



  • Und wer schreibt? Und wie synchronisierst du Lesen und Schreiben?



  • Eine CodeSys SPS schreibt.

    Im Test wurde einmal geschrieben mit der SPS. Dadurch ist synchronisierne ja nicht das Problem.

    Wie gesagt, die Dtaen kann man sehen mit Breakpoints im Watch Fenster



  • Dann machst du wohl bei der Ausgabe etwas falsch.



  • wie sollte man einen Int16 der Struktur auf der Konsole ausgeben?

    Console.WriteLine(GVL.SmIn.eMailIn.port);
    


  • Wenn die Konsole "leer" ist, wird dieser Code wohl nie ausgeführt.

    Wenn man dir den Code nicht Zeile für Zeile aus der Nase ziehen müsste, wären wir wohl schon weiter...



  • ja gut. Hier ist das Prog.:

    VARAIBLENDEKLARATION:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices; //NEU
    using System.Text;
    using System.Threading.Tasks;
    
    namespace iViewExtension
    {
    
        public struct DataExchangeEmailIn // => MELDUNG: Unsafe code may only appear if compilling with / unsafe 
        {
            public byte stateIn;
            public Int32 port; 
            public string server;
            public string absender;
            public string empfaenger;
            public string nachricht;
            public string betreff;
            public string user;
            public string passwort;
            public string iViewId;
            public byte controlIn;
        }
    
        public struct DataExchangeEmailOut
        {
            public  byte controlOut;  // von C# an PLC/ Bit 0 = True - neue Done;
        }
        public struct DataExchangeIn
        {
            public DataExchangeEmailIn eMailIn;
        }
        public struct DataExchangeOut
        {
            public DataExchangeEmailOut eMailOut;
        }
    
        public static class GVL
        {
            public static DataExchangeIn SmIn;
            public static DataExchangeOut SmOut;
            public static DataExchangeEmailIn eMailToIgm;
        }
    }
    

    ________________________________________________________________________________
    MAIN

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    
    namespace iViewExtension
    {
         class Program
        {
    
            static void Main(string[] args)
            {     
                while (true)
                {
                    //Read Data from Shared Memory
                    SharedMemoryRead ShareMemRd = new SharedMemoryRead();
                    GVL.SmIn = ShareMemRd.Mem();
    
                    // Write Data to Shared Memory               
                    /*  SharedMemoryWrite ShareMemWr = new SharedMemoryWrite();
                      ShareMemWr.Mem(GVL.SmOut) */
                    ;
    
                    Console.WriteLine(GVL.SmIn.eMailIn.port);
    
                    // sende eMail - costumer
                    //   int state = eMail.sendMail(SmIn.eMailIn);              
                }
            }
        } 
    }
    

    _____________________________________________________________________________
    MAPPED FILE READ CLASS

    using System;
    using System.IO.MemoryMappedFiles;
    using System.Runtime.InteropServices;
    using System.Text;
    using System.Threading;
    
    namespace iViewExtension
    {
        class SharedMemoryRead
        {
            unsafe public struct DataExchangeEmailInTmp
            {
                public Int16 port;
                public byte stateIn;
                public fixed byte server[256];
                public fixed byte absender[256];
                public fixed byte empfaenger[256];
                public fixed byte nachricht[256];
                public fixed byte betreff[256];
                public fixed byte user[256];
                public fixed byte passwort[256];
                public fixed byte iViewId[256];
                public byte controlIn;
            }
    
            unsafe public string getStrng(byte* fixedbyteArr)
            {
                byte[] TmpArrayB = new byte[256];
    
                for (int i = 0; i<256; i++)
                {
                    TmpArrayB[i] = fixedbyteArr[i];
                }
                return Encoding.UTF8.GetString(TmpArrayB, 0, 255);
            }
    
            unsafe public DataExchangeIn Mem()
            {
                DataExchangeEmailInTmp dataExchangeReadTmp;
                DataExchangeIn dataExchangeRead;
    
                // init
                dataExchangeRead.eMailIn.absender = "";
                dataExchangeRead.eMailIn.betreff = "";
                dataExchangeRead.eMailIn.empfaenger = "";
                dataExchangeRead.eMailIn.iViewId = "";
                dataExchangeRead.eMailIn.nachricht = "";
                dataExchangeRead.eMailIn.passwort = "";
                dataExchangeRead.eMailIn.server = "";
                dataExchangeRead.eMailIn.user = "";
                dataExchangeRead.eMailIn.port = 0;
                dataExchangeRead.eMailIn.stateIn = 0;
                dataExchangeRead.eMailIn.controlIn = 0;
    
                // get size
                int dataSIze = Marshal.SizeOf(typeof(DataExchangeEmailInTmp));
    
                // Open a mapped file with read access and one with write access. 
                //  using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
                using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
                using (var accessorRead = mmfRead.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Read))
    
                // Read the structure
                accessorRead.Read(0, out dataExchangeReadTmp);
    
                dataExchangeRead.eMailIn.port = dataExchangeReadTmp.port;
                dataExchangeRead.eMailIn.controlIn = dataExchangeReadTmp.controlIn;
                dataExchangeRead.eMailIn.stateIn = dataExchangeReadTmp.stateIn;
    
                // convert STRUCT byte arrays to string
                dataExchangeRead.eMailIn.betreff = getStrng(dataExchangeReadTmp.betreff);
                dataExchangeRead.eMailIn.absender = getStrng(dataExchangeReadTmp.absender);
                dataExchangeRead.eMailIn.server = getStrng(dataExchangeReadTmp.server);
                dataExchangeRead.eMailIn.empfaenger = getStrng(dataExchangeReadTmp.empfaenger);
                dataExchangeRead.eMailIn.iViewId = getStrng(dataExchangeReadTmp.iViewId);
                dataExchangeRead.eMailIn.nachricht = getStrng(dataExchangeReadTmp.nachricht);
                dataExchangeRead.eMailIn.passwort = getStrng(dataExchangeReadTmp.passwort);
                dataExchangeRead.eMailIn.user = getStrng(dataExchangeReadTmp.user);
    
                return dataExchangeRead; // STRUCT Mit STrings anstelle char[255]                   
            } 
        }
    }
    


  • Kann es sein, daß du die "using"-Anweisung nicht verstehst (deine Einrückung deutet jedenfalls darauf hin)?
    So interpretiert es der Compiler:

    using (var mmfRead = MemoryMappedFile.CreateOrOpen("_CODESYS_SharedMemoryTest_Write", dataSIze))
    using (var accessorRead = mmfRead.CreateViewAccessor(0, dataSIze, MemoryMappedFileAccess.Read))
    {
        // Read the structure
        accessorRead.Read(0, out dataExchangeReadTmp);
    }
    

    Danach wird die MemoryMappedFile-Instanz wieder disposed (denn das ist der Sinn von "using"-Anweisungen!



  • ja das stimmt schon.
    Using ist mir fremd. Hab eigentlich eher mit C und IEC-ST zu tun.



  • wie wird using so angewendet, dass die Insatnz nicht vom GC freigeben wird. Soweit ich das Verstanden habe, wird die Instanz sofort zerstört/ der Speicher freigegeben.



  • Erzeuge mal testweise dafür Klassenmember-Variablen und erzeuge die Instanzen im (neu anzulegenden) Konstruktor der Klasse.