NamedPipeClientStream.Write не возвращается - PullRequest
0 голосов
/ 14 ноября 2018

Я пытаюсь разработать два приложения, которые во время работы общаются друг с другом через именованные каналы, серверное приложение создает два канала, один для отправки данных клиентам, другой для получения данных из него.

Операции записи и чтения обрабатываются в другом потоке с помощью Задачи, при создании каналов или подключении к ним нет проблем.

Существует проблема, когда клиент пытается записать данные в канал,после вызова метода Write выполнение просто останавливается.

//Server code

//NamedPipesManager is a class created by me.

            while (!TasksStopper.IsCancellationRequested)
            {
                if (!NamedPipesManager.IsConnected(OutPipe) & !NamedPipesManager.IsConnected(InPipe))
                {
                    OutPipe.WaitForConnection();
                    InPipe.WaitForConnection();
                }
                CanReceiveMessages.WaitOne(); //The server start reading data only when signaled by the client, so that there is always data to read.
                MessagesSemaphore.WaitOne(); //The methods of the class can be run only by one thread at a time, a Semaphore is used to regulate access.
                NamedPipesManager.ReceiveMessage(InPipe, out MessageReceived.MessageType, out MessageReceived.Response);
                if (MessageReceived.MessageType == NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST)
                {
                    MessagesSemaphore.WaitOne();
                    NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST, Convert.ToString(CustomProjectsPath));
                }
                else if (MessageReceived.MessageType == NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST)
                {
                    MessagesSemaphore.WaitOne();
                    NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST, DefaultProjectsPath);
                }
            }
            if (NamedPipesManager.IsConnected(OutPipe))
            {
                MessagesSemaphore.WaitOne();
                NamedPipesManager.SendMessage(OutPipe, NamedPipesManager.MESSAGES.DISCONNECT, null);
                OutPipe.WaitForPipeDrain();
            }

//Client code

            NamedPipeClientStream HubInPipe = null;
            NamedPipeClientStream HubOutPipe = null;
            while (!TasksStopper.IsCancellationRequested)
            {
                HubInPipe = NamedPipesManager.ConnectToNamedPipe(null, "ProjectExchangeAppOutPipe", NamedPipesManager.PIPE_DIRECTION.IN);
                HubInPipe.ReadMode = PipeTransmissionMode.Message;
                HubOutPipe = NamedPipesManager.ConnectToNamedPipe(null, "ProjectExchangeAppInPipe", NamedPipesManager.PIPE_DIRECTION.OUT);
                HubOutPipe.ReadMode = PipeTransmissionMode.Message;
                PipesConnectedEvent.Set();
                SendMessageEvent.WaitOne();
                MessagesSemaphore.WaitOne();
                NamedPipesManager.SendMessage(HubOutPipe, MessageType, MessageToSend);
                HubWaitHandle.Set();
                MessagesSemaphore.WaitOne();
                NamedPipesManager.ReceiveMessage(HubInPipe, out ReceivedMessage.MessageType, out ReceivedMessage.Response);
                if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.CUSTOM_PROJECT_PATH_REQUEST || ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.DEFAULT_PROJECTS_PATH_REQUEST)
                {
                    ReceivedMessages.Add(ReceivedMessage);
                    MessageReceivedEvent.Set();
                }
                else if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.SETTINGS_PROFILE_CHANGED)
                {
                    DialogResult result = MessageBox.Show("...", "Avviso", MessageBoxButtons.YesNo, MessageBoxIcon.Warning);
                    if (result == DialogResult.Yes)
                    {
                        ProfileName = ReceivedMessage.Response;
                    }
                }
                else if (ReceivedMessage.MessageType == NamedPipesManager.MESSAGES.DISCONNECT)
                {
                    NamedPipesManager.ClosePipe(HubInPipe);
                    NamedPipesManager.ClosePipe(HubOutPipe);
                }
            }
            if (NamedPipesManager.IsConnected(HubInPipe) & NamedPipesManager.IsConnected(HubOutPipe))
            {
                NamedPipesManager.ClosePipe(HubInPipe);
                NamedPipesManager.ClosePipe(HubOutPipe);
            }
            else if (NamedPipesManager.IsConnected(HubInPipe) & !NamedPipesManager.IsConnected(HubOutPipe))
            {
                NamedPipesManager.ClosePipe(HubInPipe);
            }
            else if (!NamedPipesManager.IsConnected(HubInPipe) & NamedPipesManager.IsConnected(HubOutPipe))
            {
                NamedPipesManager.ClosePipe(HubOutPipe);
            }

//SendMessage method of NamedPipesManager class.

            if (Message != null)
            {
                byte[] Buffer = Encoding.Default.GetBytes(MessageType.ToString("D") + " " + Message);
                Pipe.Write(Buffer, 0, Buffer.Length); //L'esecuzione si blocca qui.
            }
            else
            {
                byte[] Buffer = Encoding.Default.GetBytes(MessageType.ToString("D"));
                Pipe.Write(Buffer, 0, Buffer.Length); //L'esecuzione si blocca qui.
            }
            Semaphore.Release();

//ReceiveMessage method of NamedPipesManager class

            MessageType = MESSAGES.NONE;
            Message = null;
            System.Diagnostics.Debugger.Break();
            StringBuilder sb = new StringBuilder();
            byte[] Buffer = new byte[10];
            string Chunk = string.Empty;
            while (Pipe.IsConnected)
            {
                int BytesRead = Pipe.Read(Buffer, 0, Buffer.Length);
                do
                {
                    Chunk = Encoding.Default.GetString(Buffer);
                    sb.Append(Chunk);
                    Buffer = new byte[10];
                }
                while (!Pipe.IsMessageComplete);
                string MessageReceived = sb.ToString();
                MessageType = (MESSAGES)Convert.ToInt32(MessageReceived[0].ToString());
                if (MessageReceived.Length > 1)
                {
                    Message = MessageReceived.Substring(3);
                }
            }
            Semaphore.Release();
...