Створити

Приклад роботи з File Mapping в C#

Робив я знач останню лабортарну, доробив і такий: 

А чо б не надати приклад роботи з цією штукою?

Загалом я не дуже знаю де це може використовуватись, але приклад накидати зміг. Повний код буде в кінці посту, а тут буду робити пояснення того що в ньому написано.

Для початку ремарка, що в мене реалізація винесена в динамічну бібліотеку класів, тому звернення до неї відповідне, але можна її використовувати і як звичайний клас.

Повідомлення для відправки у File Mapping. Розмір повідомлення можете встановити будь-який. Можете навіть спробувати погратись і зробити його динамічним

Клас з функціями відправки і отримання повідомлень. В конструкторі створюємо м'ютекс (штука для утримання ресурсів від використання двома процесами одночасно). Він нам потрібен один, так шо перевіряємо чи він в нас вже є. Також в тому ж конструкторі створюємо або відкриваємо (якщо вона вже існує) нашу область пам'яті File Mapping.

Функція відправки повідомлення. Ну як відправки, ми наше повідомлення конвертуємо в байтовий масив і записуємо в пам'ять. Також можете помітити як використовуються м'ютекси. Перший виклик резервує ресурс під цей процес якшо він вільний, або ж ставить функцію в очікування, якщо ресурс кимось задіяний, а останній виклик відпускає ресурс і сигналізує всім хто його очікує що можна брати.

Функція отримання повідомлення (читай зчитування з пам'яті). Знову ті ж таки м'ютекси, адже це використання однієї області пам'яті. Тут окрім зчитування, відбувається конвертація байтового масиву в рядок і повернення цих даних кудись там де їх очікують.

А це використання цих функцій на простенькому прикладі відправки тексту.

Даємо м'ютексу і області пам'яті імена, адже їх розрізняють саме за ними. Тобто у вас може бути декілька областей пам'яті, і відповідно на кожну з них треба свій м'ютекс.

Далі створюємо два різних обєкти одного класу. В конструктор я передаю імена одного й того ж м'ютексу і пам'яті, адже ці об'єкти працюватимуть саме з ними.

Ну а далі просто викликаю потрібні мені функції через об'єкти класу. В результаті у вас на екран виведеться повідомлення яке ви відправите

Це власне реалізація

using System.IO.MemoryMappedFiles;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;

namespace MessageFunctions
{
    internal class Message
    {
        // Структура повідомлення
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct MessageData
        {
            [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
            public string Content;
        }

        // Розмір повідомлення
        public const int MessageSize = 256 * 2; // Розмір у байтах для Unicode-рядка
    }
    public class MessageFunction
    {
        private MemoryMappedFile memoryMappedFile;
        private Mutex mutex;

        bool createMutex = false;

        public MessageFunction(string mutexName, string memoryMappedFileName)
        {
            if(createMutex == false) mutex = new Mutex(true, mutexName);
            createMutex = true;

            memoryMappedFile = MemoryMappedFile.CreateOrOpen(memoryMappedFileName, Message.MessageSize);
        }

        public void SendMessage(string content)
        {
            mutex.WaitOne();

            using (var accessor = memoryMappedFile.CreateViewAccessor())
            {
                // Перетворюємо рядок у байти
                byte[] contentBytes = Encoding.Unicode.GetBytes(content);

                // Записуємо байти у область пам'яті
                accessor.WriteArray(0, contentBytes, 0, contentBytes.Length);
            }

            mutex.ReleaseMutex();
        }

        public string ReceiveMessage()
        {
            mutex.WaitOne();

            using (var accessor = memoryMappedFile.CreateViewAccessor())
            {
                // Створюємо буфер для зчитування байтів
                byte[] contentBytes = new byte[Message.MessageSize];

                // Зчитуємо байти з області пам'яті
                accessor.ReadArray(0, contentBytes, 0, contentBytes.Length);

                // Перетворюємо байти у рядок
                string receivedMessage = Encoding.Unicode.GetString(contentBytes);

                // Повертаємо отримане повідомлення
                return receivedMessage;
            }

            mutex.ReleaseMutex();
        }
    }
}

А це приклад використання


using MessageFunctions;
class Program
{
    static void Main()
    {
        // Ім'я м'ютексу та файлу області пам'яті
        string mutexName = "MyMutex";
        string memoryMappedFileName = "MyMemoryMappedFile";

        // Приклад використання
        var sender = new MessageFunction(mutexName, memoryMappedFileName);
        var receiver = new MessageFunction(mutexName, memoryMappedFileName);
        
        
        // Відправлення повідомлення
        sender.SendMessage("Hello, World!");

        // Отримання та виведення повідомлення
        string receivedMessage = receiver.ReceiveMessage();
        Console.WriteLine("Received Message: " + receivedMessage);
    }
}

Якщо будуть якісь питання - пишіть в коментарях, але так як я сам про цю штуку дізнався за декілька годин до написання посту, то напевно сильно не допоможу

1 коментар

Увійдіть, щоб коментувати.
2 бали
Поскаржитись

Ух єбать я пост накатав про програмування. Аж сам від себе не очікував. Код якшо шо генерував Чат ГПТ, але в нього на це пішло незліченна кількість спроб і декілька нових чатів шоб він втратив контекст коли зациклювався на одному й тому ж