Я пытаюсь разработать два приложения, которые во время работы общаются друг с другом через именованные каналы, серверное приложение создает два канала, один для отправки данных клиентам, другой для получения данных из него.
Операции записи и чтения обрабатываются в другом потоке с помощью Задачи, при создании каналов или подключении к ним нет проблем.
Существует проблема, когда клиент пытается записать данные в канал,после вызова метода 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();