none
MemoryMappedFile, persistance and @Could not find a part of the path@ error RRS feed

  • Question

  • I created 2 class 1 that send to the file and one that reads, I am using the persistent option.

    1. on the MemoryMappedFile.OpenExisting I get error that "Could not find a part of the path"

    not clear why it happends?

    2. when I read the data out it's actually erased? or if I run the process again the items will be read again?

    my target is pass data between 2 process.

    this is the class that send data to the file:

    private const int MMF_MAX_SIZE = 1024;  // allocated memory for this memory mapped file (bytes)
            private const int MMF_VIEW_SIZE = 1024*10; // how many bytes of the allocated memory can this process access
            private readonly string filePath;
            private readonly Thread thread;
    
            public Sender(string filePath)
            {
                this.filePath = filePath;
                thread=new Thread(Send);
                thread.Start();
            }
    
            public void Send()
            {
                ManageQueue manageQueue = ManageQueue.Instance;
                MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null,MMF_VIEW_SIZE ,MemoryMappedFileAccess.ReadWrite);
                // creates a stream for this process, which allows it to write data from offset 0 to 1024 (whole memory)
                MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE);
                SmsMessage smsMessage = null;
                while (true)
                {
                    while (manageQueue.incomingMessages.IsEmpty) ;
                    if (manageQueue.incomingMessages.TryDequeue(out smsMessage))
                    {
                        // serialize the variable 'message1' and write it to the memory mapped file
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(mmvStream, smsMessage);
                        mmvStream.Seek(0, SeekOrigin.Begin); // sets the current position back to the beginning of the stream
                    }
                }//while(true)
            }//Send() // the memory mapped file lives as long as this process is running
        }

    this is the reader class :

    private const int MMF_MAX_SIZE = 1024;  // allocated memory for this memory mapped file (bytes)
            private const int MMF_VIEW_SIZE = 1024; // how many bytes of the allocated memory can this process access
            private readonly string filePath;
            private readonly Thread thread;
    
            public Listener(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Receiver);
                thread.Start();
            }
            public void Receiver()
            {
                
                // creates the memory mapped file
                MemoryMappedFile mmf = MemoryMappedFile.OpenExisting(filePath,MemoryMappedFileRights.Read);
                MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE); // stream used to read data
                BinaryFormatter formatter = new BinaryFormatter();
                byte[] buffer = new byte[MMF_VIEW_SIZE];
                SmsMessage smsMessage;
                while (true)
                {
                    // reads every second what's in the shared memory
                    while (mmvStream.CanRead)
                    {
                        // stores everything into this buffer
                        mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
    
                        // deserializes the buffer & prints the message
                        smsMessage = (SmsMessage)formatter.Deserialize(new MemoryStream(buffer));
                        Console.WriteLine(smsMessage.Text + "\n" + smsMessage.CreateDateTime + "\n");
                        //System.Threading.Thread.Sleep(1000);
                    }
                    Thread.Sleep(1000);
                }//while (true)
            }

    thanks

    Wednesday, June 26, 2019 9:00 AM

All replies

  • Hi want 2 Learn, 

    Thank you for posting here.

    For your question, I try to make a test, but I can’t find more information about ‘ManageQueue’ and ‘SmsMessage’.

    Please provide more details about them, and it will help us to do the test.

    We are waiting for your update.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, June 27, 2019 1:57 AM
    Moderator
  • Hi, SmsMessage is a class with few string fields.

    ManageQueue is a singleton

    which has a defenition

    public  readonly ConcurrentQueue<SmsMessage> incomingMessages;

    Thursday, June 27, 2019 8:43 AM
  • Hi want 2 Learn, 

    Thanks for your feedback,

    I have made a test on my side, we can use Sender class to generate data and use Reader class to read the data.

    Here’s the code:

        public class Sender
        {
            private const int MMF_MAX_SIZE = 1024;  
            private const int MMF_VIEW_SIZE = 1024 * 10; 
            private readonly string filePath;
            private readonly Thread thread;
            public Sender(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Send);
                thread.Start();
            }
            public void Send()
            {
                ManageQueue manageQueue = ManageQueue.Instance;
                MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite);
                MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE);
                SmsMessage smsMessage = new SmsMessage();
                smsMessage.Text = "hello";
                smsMessage.CreateDateTime = "2018";
                while (true)
                {
                    //while (manageQueue.incomingMessages.IsEmpty) ;
                    //if (manageQueue.incomingMessages.TryDequeue(out smsMessage))
                    //{
                        // serialize the variable 'message1' and write it to the memory mapped file
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(mmvStream, smsMessage);
                        mmvStream.Seek(0, SeekOrigin.Begin); 
                    //}
                }
            }
        }
        public  class Reader
        {
            private const int MMF_MAX_SIZE = 1024;  
            private const int MMF_VIEW_SIZE = 1024*10; 
            private readonly string filePath;
            private readonly Thread thread;
            public Reader(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Receiver);
                thread.Start();
            }
            public void Receiver()
            {
                using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, "logmap", 10000000))
                {
                    // The following URL can help you solve the first problem, but I don't use the method.
                    // URL: https://stackoverflow.com/questions/25625541/file-exists-returns-true-and-openexisting-fails-with-directorynotfoundexception
                    //MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.Read);
                    using (MemoryMappedViewStream mmvStream = memoryMapped.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        byte[] buffer = new byte[MMF_VIEW_SIZE];
                        SmsMessage smsMessage;
                        while (true)
                        {
                            while (mmvStream.CanRead)
                            {
                                mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                                smsMessage = (SmsMessage)formatter.Deserialize(new MemoryStream(buffer));
                                Console.WriteLine(smsMessage.Text + "\n" + smsMessage.CreateDateTime + "\n");
                            }
                            Thread.Sleep(1000);
                        }
                    } 
                }
            }
        }

    Result of my test:


    Hope it can help you.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Friday, June 28, 2019 7:29 AM
    Moderator
  • Hi,

    1. try to run both of them at the same time ,this is my purpose of my use.

    2. in the OpenExistingjust change he permission to ReadWrite

     MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.ReadWrite);

    3. try this, and you will see you can't read all the data from the file.

    my target was to get data between process at real time.

    Friday, June 28, 2019 3:46 PM
  • Hi want 2 Learn, 

    Thanks for your feedback.

    I have updated my code, it can run both of ‘Sender()’ and ‘Reader()’ method at the same time.

    The following is the code:

            public void Send()
            {
                ManageQueue manageQueue = ManageQueue.Instance;
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite))
                {
                    using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        SmsMessage smsMessage = new SmsMessage();
                        smsMessage.Text = "bye";
                        smsMessage.CreateDateTime = "2018";
                        SmsMessage sm = new SmsMessage();
                        sm.Text = "hello";
                        sm.CreateDateTime = "2019";
                        List<SmsMessage> list = new List<SmsMessage>();
                        list.Add(smsMessage);
                        list.Add(sm);
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(mmvStream, list);
                        mmvStream.Seek(0, SeekOrigin.Begin);
                    }
                }    
            }
            public void Receiver()
            {
                using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, "logmap", 10000000))
                {
                    MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.ReadWrite);
                    using (MemoryMappedViewStream mmvStream = memoryMapped.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        byte[] buffer = new byte[MMF_VIEW_SIZE];
                        List<SmsMessage> list = new List<SmsMessage>();
                        while (true)
                        {
                            mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                            list = (List<SmsMessage>)formatter.Deserialize(new MemoryStream(buffer));
                            foreach (var item in list)
                            {
                                Console.WriteLine(item.Text);
                                Console.WriteLine(item.CreateDateTime);
                                Console.WriteLine();
                            }                      
                            Thread.Sleep(1000);
                        }
                    }               
                }
            }
            static void Main(string[] args)
            {
                string path = @"D:\client.txt";
                if (!File.Exists(path))
                {
                    Sender sender = new Sender(path);
                }
                Thread.Sleep(2000);
                Reader r = new Reader(path);
                Console.WriteLine("success");
                Console.ReadKey();           
            }

    Result :



    Best Regards,

    Xingyu Zhao



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 2, 2019 9:07 AM
    Moderator
  • Actually, Xingyu, your code does NOT allow both threads to run at the same time.  After the file is created, your code ONLY runs the reader.  If you delete D:\client.txt or remove the check on File.Exists, you'll see that it fails in Listener.Receiver because the file "is being used by another process" (which is actually another thread in OUR process).

    This is caused by what I consider to be a rather serious bug in the CLR MemoryMappedFile implementation: if you allow CreateFromFile to create the file, it stupidly uses FileShare.None, which means no one else is allowed to open the file.  The only way around this is to create the file as a FileStream, specifying the sharing options, and use another overload of CreateFromFile.

    This works:

        public void Send()
        {
            FileStream fs = new FileStream( filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite );
            MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true );
            // creates a stream for this process, which allows it to write data from offset 0 to 1024 (whole memory)
            MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE);
            ...
        }
    
        public void Receiver()
        {
            FileStream fs = new FileStream( filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite );
            // creates the memory mapped file
            MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null,   MMF_VIEW_SIZE ,MemoryMappedFileAccess.Read, HandleInheritability.None, true );
            MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE, MemoryMappedFileAccess.Read); // stream used to read data
            ...
        }
    
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Tuesday, July 2, 2019 7:00 PM
  • Hi, thanks both of you I did a progress.\last problem that left that on the Receiver I get the same values

    all the time, I can't find the reason (in the sender I see in the while loop that the random values change all the time)

    any idea?

    ;

    thanks

    Wednesday, July 3, 2019 10:00 PM
  • Hi want 2 Learn, 

    It is most likely that the bool value in while loop is true.

    Try not to use loop:

                        //while (true)
                        //{
                        //    while (mmvStream.CanRead)
                        //    {
                                mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                                list = (List<SmsMessage>)formatter.Deserialize(new MemoryStream(buffer));
                                foreach (var item in list)
                                {
                                    Console.WriteLine(item.Text);
                                    Console.WriteLine(item.CreateDateTime);
                                    Console.WriteLine();
                                }
                                Thread.Sleep(1000);
                        //    }
                        //}

    Best Regards,

    Xingyu Zhao



    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Thursday, July 4, 2019 6:12 AM
    Moderator
  • not to use 

    while (mmvStream.CanRead)

    Thursday, July 4, 2019 2:09 PM
  • Hi Xingyu Zhao,

    I am still getting the same values.

    I assume we needto use offset or something like that because it seems we read all the time from start of memory

    Thursday, July 4, 2019 2:12 PM
  • Hi want 2 Learn,

    Sorry to keep you waiting,

    Could you provide some code here? I use the code to do the test, but I get the result one time.

    My code:

            public void Receiver()
            {
                using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, "logmap", 10000000))
                {
                    MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.ReadWrite);
                    using (MemoryMappedViewStream mmvStream = memoryMapped.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        byte[] buffer = new byte[MMF_VIEW_SIZE];
                        List<SmsMessage> list = new List<SmsMessage>();
    
                        mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                        list = (List<SmsMessage>)formatter.Deserialize(new MemoryStream(buffer));
                        foreach (var item in list)
                        {
                            Console.WriteLine(item.Text);
                            Console.WriteLine(item.CreateDateTime);
                            Console.WriteLine();
                        }
                        Thread.Sleep(1000);
                    }
                }
            }

    Result:


    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 10, 2019 7:57 AM
    Moderator
  • Hi Xingyu Zhao,

    first thanks for all the help!

    using System;
    
    namespace Sender
    {
        [Serializable]
        public class SmsMessage
        {
            public int x;
            public int y;
            public SmsMessage(int x, int y)
            {
                this.x = x;
                this.y = y;
            }
        }
    }
    

    SENDER

    using System;
    using System.IO;
    using System.IO.MemoryMappedFiles;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Threading;
    
    namespace Sender
    {
        public class Sender
        {
            private const int MMF_MAX_SIZE = 1024;
            private const int MMF_VIEW_SIZE = 1024 * 10;
            private readonly string filePath;
            private readonly Thread thread;
            private Random rnd = new Random();
            public Sender(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Send);
                thread.Start();
            }
            public void Send()
            {
    
                FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true))
                {
                    // creates a stream for this process, which allows it to write data from offset 0 to 1024 (whole memory)
                    using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE)) { 
    
    
    
                        while (true)
                        {
                            //while (manageQueue.incomingMessages.IsEmpty) ;
                            //if (manageQueue.incomingMessages.TryDequeue(out smsMessage))
                            //{
                            // serialize the variable 'message1' and write it to the memory mapped file
                            SmsMessage smsMessage = new SmsMessage(rnd.Next(1, 20000), rnd.Next(1, 2000));
                            BinaryFormatter formatter = new BinaryFormatter();
                            formatter.Serialize(mmvStream, smsMessage);
                            mmvStream.Seek(0, SeekOrigin.Begin);
                            Thread.Sleep(1000);
                            //}
                        }
                    }
                }
            }
    
        }
    }
    

    RECIVER (with your last fix

    using Sender;
    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.IO.MemoryMappedFiles;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Threading;
    
    namespace Reciver
    {
        public class R2
        {
            private const int MMF_MAX_SIZE = 1024;
            private const int MMF_VIEW_SIZE = 1024 * 10;
            private readonly string filePath;
            private readonly Thread thread;
            public R2(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Receiver);
                thread.Start();
            }
    
            private void Receiver()
            {
                using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, "logmap", 10000000))
                {
                    MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.ReadWrite);
                    using (MemoryMappedViewStream mmvStream = memoryMapped.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        byte[] buffer = new byte[MMF_VIEW_SIZE];
                        List<SmsMessage> list = new List<SmsMessage>();
    
                        mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                        list = (List<SmsMessage>)formatter.Deserialize(new MemoryStream(buffer));
                        foreach (var item in list)
                        {
                            Console.WriteLine(item.x);
                            Console.WriteLine(item.y);
                            Console.WriteLine();
                        }
                        Thread.Sleep(1000);
                    }
                }
            }
    
    
        }
    }
    
    i try 2 run it from 2 different VS and still not works

    Wednesday, July 10, 2019 5:37 PM
  • Hi Xingyu Zhao,

    any idea?

    Tuesday, July 16, 2019 11:59 AM
  • Hi want 2 Learn,

    Thanks for your feedback.

    Try to remove 'while(true)' in Send method:

            public void Send()
            {
                FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true))
                {
                    // creates a stream for this process, which allows it to write data from offset 0 to 1024 (whole memory)
                    using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        //while (true)
                        //{
                            //while (manageQueue.incomingMessages.IsEmpty) ;
                            //if (manageQueue.incomingMessages.TryDequeue(out smsMessage))
                            //{
                            // serialize the variable 'message1' and write it to the memory mapped file
                            SmsMessage smsMessage = new SmsMessage(rnd.Next(1, 20000), rnd.Next(1, 2000));
                            BinaryFormatter formatter = new BinaryFormatter();
                            formatter.Serialize(mmvStream, smsMessage);
                            mmvStream.Seek(0, SeekOrigin.Begin);
                            Thread.Sleep(1000);
                            //}
                        //}
                    }
                }
            }

    Hope it can help you.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, July 23, 2019 8:00 AM
    Moderator
  • if you remove while(true) it mean you will exist after sending 1 object

    and the Receiver will fail

    Tuesday, July 23, 2019 10:27 AM
  • You are not storing a List<SmsMessage> in the file, so why do you think you should be able to read one?  If you store an SmsMessage, then you need to read an SmsMessage.  If you want to read a list, then you have to store a list.

    Look, this application seems to do exactly what you want.  You'll need to change the file name.

    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.IO;
    using System.IO.MemoryMappedFiles;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Threading;
    using System.Runtime.InteropServices;
    
    [Serializable]
    public class SmsMessage
    {
        public int x;
        public int y;
        public SmsMessage(int x, int y)
        {
            this.x = x;
            this.y = y;
        }
    }
    
    class Sender
    {
        // allocated memory for this memory mapped file (bytes)
        private const int MMF_MAX_SIZE = 1024;
        // how many bytes of the allocated memory can this process access
        private const int MMF_VIEW_SIZE = 1024*10;
        private readonly string filePath;
        private Random rnd = new Random();
        private readonly Thread thread;
    
        public Sender(string filePath)
        {
            this.filePath = filePath;
            thread = new Thread(Send);
            thread.Start();
        }
    
        public void Send()
        {
            FileStream fs = new FileStream(filePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite);
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite, HandleInheritability.None, true))
            {
                using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE))
                    while( true)
                    {
                        SmsMessage smsMessage = new SmsMessage(rnd.Next(1,20000),rnd.Next(1,20000));
                        BinaryFormatter formatter = new BinaryFormatter();
                        Console.WriteLine("SENT {0}", smsMessage.x);
                        Console.WriteLine("SENT {0}", smsMessage.y);
                        formatter.Serialize(mmvStream, smsMessage);
                        mmvStream.Seek(0, SeekOrigin.Begin);
                        Thread.Sleep( 1000 );
                    }
            }    
        }
    }
    
    
    class Listener
    {
        // allocated memory for this memory mapped file (bytes)
        private const int MMF_MAX_SIZE = 1024;
        // how many bytes of the allocated memory can this process access
        private const int MMF_VIEW_SIZE = 1024*10;
        private readonly string filePath;
        private readonly Thread thread;
    
        public Listener(string filePath)
        {
            this.filePath = filePath;
            thread = new Thread(Receiver);
            thread.Start();
        }
    
        public void Receiver()
        {
            FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
            using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(fs, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.Read, HandleInheritability.None, true))
            {
                using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE, MemoryMappedFileAccess.Read))
                {
                    BinaryFormatter formatter = new BinaryFormatter();
                    byte[] buffer = new byte[MMF_VIEW_SIZE];
                    while (true)
                    {
                        mmvStream.Seek(0, SeekOrigin.Begin);
                        mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
    
                        SmsMessage item = (SmsMessage)formatter.Deserialize(new MemoryStream(buffer));
                        Console.WriteLine(item.x);
                        Console.WriteLine(item.y);
                        Thread.Sleep(1000);
                    }
                }               
            }
        }
    }
    
    class Example 
    {
        static void Main(string[] args)
        {
            string path = "c:/tmp/one.dat";
            Sender sender = new Sender(path);
            Thread.Sleep(1000);
            Listener r = new Listener(path);
            Console.WriteLine("success");
            Console.ReadKey();           
        }
    }
    


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Tuesday, July 23, 2019 5:48 PM
  • Hi Tim thanks for your updated code.

    1. I want to send all the time object and read them from the other side.

    2. if you test you will see you push all the time random x&y

    but when you print what you read all the time you read over and over in the loop the first x&y to pushed to the memory, I assume it's some how issue with the offset, but I can't figure it out yet.

    Tuesday, July 23, 2019 6:45 PM
  • Hi want 2 Learn, 

    I use List<T> to store all data and serialize it in Send() method.

    Here's my whole code:

    Class Sender:

        public class Sender
        {
            private const int MMF_MAX_SIZE = 1024;  // allocated memory for this memory mapped file (bytes)
            private const int MMF_VIEW_SIZE = 1024 * 10; // how many bytes of the allocated memory can this process access
            private readonly string filePath;
            private readonly Thread thread;
    
            public Sender(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Send);
                thread.Start();
            }
    
            public void Send()
            {
                ManageQueue manageQueue = ManageQueue.Instance;
                using (MemoryMappedFile mmf = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, null, MMF_VIEW_SIZE, MemoryMappedFileAccess.ReadWrite))
                {
                    using (MemoryMappedViewStream mmvStream = mmf.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        SmsMessage smsMessage = new SmsMessage();
                        smsMessage.Text = "bye";
                        smsMessage.CreateDateTime = "2018";
                        SmsMessage sm = new SmsMessage();
                        sm.Text = "hello";
                        sm.CreateDateTime = "2019";
                        List<SmsMessage> list = new List<SmsMessage>();
                        list.Add(smsMessage);
                        list.Add(sm);
                        BinaryFormatter formatter = new BinaryFormatter();
                        formatter.Serialize(mmvStream, list);
                        mmvStream.Seek(0, SeekOrigin.Begin);
                    }
                }    
            }
        }

    Class Reader:

        public  class Reader
        {
            private const int MMF_MAX_SIZE = 1024;  // allocated memory for this memory mapped file (bytes)
            private const int MMF_VIEW_SIZE = 1024*10; // how many bytes of the allocated memory can this process access
            private readonly string filePath;
            private readonly Thread thread;
    
            public Reader(string filePath)
            {
                this.filePath = filePath;
                thread = new Thread(Receiver);
                thread.Start();
            }
            public void Receiver()
            {
                using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(filePath, FileMode.OpenOrCreate, "logmap", 10000000))
                {
                    MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("logmap", MemoryMappedFileRights.ReadWrite);
                    using (MemoryMappedViewStream mmvStream = memoryMapped.CreateViewStream(0, MMF_VIEW_SIZE))
                    {
                        BinaryFormatter formatter = new BinaryFormatter();
                        byte[] buffer = new byte[MMF_VIEW_SIZE];
                        List<SmsMessage> list = new List<SmsMessage>();
    
                        mmvStream.Read(buffer, 0, MMF_VIEW_SIZE);
                        list = (List<SmsMessage>)formatter.Deserialize(new MemoryStream(buffer));
                        foreach (var item in list)
                        {
                            Console.WriteLine(item.Text);
                            Console.WriteLine(item.CreateDateTime);
                            Console.WriteLine();
                        }
                        Thread.Sleep(1000);
    
                    }
                }
            }
        }


    Main function and class SmsMessage:

        class Program
        {
            static void Main(string[] args)
            {
                string path = @"D:\client.txt";
                if (!File.Exists(path))
                {
                    Sender1 sender = new Sender1(path);
                }
                Thread.Sleep(2000);
                Reader r = new Reader(path);
                Console.WriteLine("success");
                Console.ReadKey();           
            }
        }
    
        [Serializable]
        public class SmsMessage
        {
            public string CreateDateTime { get; set; }
            public string Text { get; set; }
        }
    
        public sealed class ManageQueue
        {
            private static ManageQueue instance = null;
            private ManageQueue() { }
    
            public readonly ConcurrentQueue<SmsMessage> incomingMessages;
    
            public static ManageQueue Instance
            {
                get
                {
                    if (instance == null)
                    {
                        instance = new ManageQueue();
                    }
                    return instance;
                }
            }
        }

    If I have any misunderstanding, please show more details.

    We are waiting for your update and glad to help you.

    Best Regards,

    Xingyu Zhao


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, July 24, 2019 8:42 AM
    Moderator
  • The writer rewinds the file back to the beginning every time it writes, and the reader rewinds to the beginning before it reads.  There will always be exactly one event in the file.  You could have the writer keep a List<MsmMessage>, then keep adding messages to the list, then Serialize the whole list out to the file.  The reader would then see the whole list.  However, how would the writer know that some of the messages had been processed?  The list would grow and grow forever.

    Are you expecting this to be some kind of circular buffer, where the writer writes multiple events, and the reader picks up whatever it hadn't read since the last time?  That's a much more complicated task, and I don't believe you will be able to use Serialize/Deserialize for this.

    If that's the kind of design you want, then a memory-mapped file is the wrong solution.  There's no way to synchronize the two ends.  Instead, you should be using a TCP socket or a named pipe.  That way, the system provides the buffering.  You can serialize the SmsMessages one at a time, and write them to the pipe.  The reader just reads from the named pipe as if it were a file.  Each new packet it gets will be a serialized object.


    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Wednesday, July 24, 2019 10:40 PM
  • Hi Tim, thanks for the reply.

    is there someting similar to infispan in C#?

    Friday, July 26, 2019 10:54 AM
  • Did you mean Infinispan?  Did you check their web site at all?  There is an Infinispan binding for C#.

    Tim Roberts | Driver MVP Emeritus | Providenza &amp; Boekelheide, Inc.

    Sunday, July 28, 2019 7:06 AM