Формы Windows службы IPC Windows

У меня проблема с ИП. Я создал в службе Windows NamedPipeServer:

serverPipe = new NamedPipeServerStream(Constants.PIPE_NAME, PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
Thread thread = new Thread(new ThreadStart(pipeWork));
thread.Start();

где находится пайпворк

private static void pipeWork()
{
    try
    {
        byte[] buffer = new byte[1024];
        while (true)
         {
            if (!serverPipe.IsConnected)
                serverPipe.WaitForConnection();
            int nr = serverPipe.Read(buffer, 0, buffer.Length);
            String str=Encoding.Default.GetString(buffer);

        …
        }
    }
    catch (Exception ex)
    {

    }
}

и в формы Windows у меня есть клиент

clientPipe = new NamedPipeClientStream(".", PhotoServiceClassLibrary.Constants.PIPE_NAME, PipeDirection.InOut,PipeOptions.Asynchronous);
                clientPipe.Connect();
                clientPipe.ReadMode = PipeTransmissionMode.Message;

pipeThread=new Thread(new ThreadStart(pipeWork));
            pipeThread.Start();

где находится пайпворк

private void pipeWork()
{
    try
    {
        while (true)
        {
            using (StreamReader sr = new StreamReader(clientPipe))
            {
                string message;

                while ((message = sr.ReadLine()) != null)
                {

                    …

                }
            }
        }
    }
    catch (Exception ex)
    {

    }
}

Я хочу, чтобы когда служба начала действие, чтобы отключить ContextMenuStrip из форм Windows, для этого служба записывает сообщение в StreamWriter sw:

        StreamWriter write = null;
        write = new StreamWriter(serverPipe);

        if (serverPipe.IsConnected)
        {
            write.Write(message);
            write.Flush();
        }

Код правильный, потому что я создал для тестирования другие формы Windows, которые реализуют те же вещи, что и служба Windows, и связь между сервером Windows Forms -> клиент Windows Forms Pipe работает хорошо. Проблема в том, что форма Windows - клиентский канал не получает сообщение от службы Windows - серверный канал.

Я знаю, что WCF может быть лучшей идеей, но я хочу понять, почему он не работает на низкоуровневом IPC. Почему? Я видел очень странное поведение. Мой сервис взаимодействует 2 раза с окнами форм: 1.Мой сервис предназначен для загрузки некоторых фотографий. Когда он начинает загрузку, он отправляет сообщение в формы Windows, чтобы сообщить ему об этом. 2. Когда я останавливаю службу, он отправляет сообщение в формы Windows, и он также останавливается. Я только что обнаружил, что оба сообщения поступают в агент Windows только после остановки службы. Может кто-нибудь объяснить, почему?


person user61652    schedule 06.06.2009    source источник


Ответы (2)


Я надеюсь, что это не ваш настоящий код. Хорошо, что у вас есть блоки try/catch вокруг кода ваших обработчиков ThreadStart (иначе исключение просто тихо удалит поток). Однако, если вы не регистрируете исключение в блоке catch, то это действительно так же плохо.

У вас есть тайна (сервер не получает сообщение), и вы скрываете информацию (произошло исключение). Если бы вы не скрывали информацию, у вас мог бы быть ответ на вашу загадку (сервер не получает сообщение, потому что произошло исключение).

person John Saunders    schedule 06.06.2009
comment
нет, это не мой настоящий код. Мой реальный код: try{ [...] } catch(exception ex) { throw ex; } - person user61652; 07.06.2009
comment
и, нет, у меня нет никакой ошибки... что я должен сделать, чтобы служба Windows общалась с формами Windows через namedpipe??? - person user61652; 07.06.2009
comment
Если вы просто собираетесь снова вызвать исключение, сделайте это; не бросать бывший;. Еще лучше, если вы просто собираетесь перебросить его, то не ловите его. Лучше поймать и записать. - person John Saunders; 07.06.2009
comment
Кроме того, я бы посоветовал держаться подальше от таких низкоуровневых механизмов и вместо этого использовать WCF. Он поддерживает именованные каналы и многие другие формы привязки, а также двоичную сериализацию, поэтому нет накладных расходов на SOAP или XML. - person John Saunders; 07.06.2009

Я пытаюсь реализовать то же самое.

Я заметил, что вы передаете перечисление PipeTransmissionMode.Message в конструкторе NamedPipeServerStream (serverPipe). Это означает, что поток будет содержать строки.

Но в pipeWork вы читаете их как массив байтов.

Посмотрите пример в этой статье на MSDN: http://msdn.microsoft.com/en-us/library/system.io.pipes.namedpipeclientstream.aspx

person Glimpse    schedule 19.08.2013