У меня есть форма Windows, в которой размещен пользовательский элемент управления. Этот пользовательский элемент управления запускает отдельный процесс (.exe), который создает и инициализирует NamedPipeServerStream. Как только процесс инициализирует NamedPipeServerStream, пользовательский элемент управления подключается к нему как NamedPipeClientStream.
Это все отлично работает.
В форме Windows у меня есть кнопка «Проверить наличие обновлений». Когда эта кнопка нажата, NamedPipeClientStream отправляет на сервер сообщение, на которое сервер отвечает, а MessageBox говорит: «Мне сказали проверять наличие обновлений». Таким образом, я могу сказать, что этот клиент> сервер работает нормально.
Вот проблема. Затем предполагается, что сервер отправляет сообщение НАЗАД клиенту, сообщая, что теперь он проверяет наличие обновлений (поэтому пользовательский элемент управления может обновлять свой статус после того, как сервер получил самую команду). Но всякий раз, когда это происходит, все блокируется.
Теперь я собираюсь предположить, что это потому, что я пытаюсь одновременно читать и записывать в Именованный канал?
Ниже приведены некоторые фрагменты кода как с сервера, так и с клиента. (Оба этих фрагмента выполняются в отдельных потоках в соответствующих процессах, чтобы не блокировать пользовательский интерфейс)
GUpdater (Сервер именованных каналов):
private void WaitForClientCommands()
{
// Wait for a connection from a Named Pipe Client (The GUpControl)
pipeStream.WaitForConnection();
pipeConnected = true;
// Create a StreamWriter/StreamReader so we can write/read to the Named Pipe
pipeStreamWriter = new StreamWriter(pipeStream) { AutoFlush = true };
pipeStreamReader = new StreamReader(pipeStream);
// Now that we have a connection, start reading in messages and processing them
while (true)
{
// Skip this time if we are currently writing to the pipe
if(isWritingToPipe) continue;
var message = pipeStreamReader.ReadLine();
if (message == null)
{
// We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
Thread.Sleep(500);
continue;
}
switch(message)
{
case "CheckForUpdates":
//MessageBox.Show("Told to check for updates");
SendMessageToClient("Checking For Updates, Woot!");
break;
case "DownloadUpdate":
MessageBox.Show("Told to download update");
break;
case "ApplyUpdate":
MessageBox.Show("Told to apply update");
break;
}
}
}
GUpControl (Клиент именованных каналов):
private void WaitForServerCommands()
{
if(!pipeConnected) return;
// Now that we have a connection, start reading in messages and processing them
while (true)
{
// Skip this time if we are currently writing to the pipe
if (isWritingToPipe) continue;
// Attempt to read a line from the pipe
var message = pipeStreamReader.ReadLine();
if (message == null)
{
// We don't want to hog up all the CPU time, so if no message was reaceived this time, wait for half a second
Thread.Sleep(500);
continue;
}
MessageBox.Show("I got a message from the server!!\r\n" + message);
}
}
Следующий фрагмент является методом, который отвечает за запись на клиент / сервер от каждого компонента. (Единственная разница в названии, то есть SendMessageToClient
и SendMessageToServer
)
private void SendMessageToServer(string message)
{
if(pipeConnected)
{
isWritingToPipe = true;
pipeStreamWriter.WriteLine(message);
isWritingToPipe = false;
}
}
Переменная isWritingToPipe
- это простое значение типа bool, которое имеет значение true, когда соответствующий процесс пытается выполнить запись в именованный канал. Это была моя первая попытка решить проблему.
Любая помощь очень ценится!