C # Pipe OperationCanceledException при запуске в качестве службы - PullRequest
1 голос
/ 04 ноября 2011

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

Когда я запускаю консольную версию моего приложения (тот же код, но инициализированный в консольном проекте), все работает нормально, но когда я запускаю служебную версию приложения (либо устанавливается с помощью проекта установки, либо с помощью VS unistallUtil.exe) Я получаю эту ошибку:

System.OperationCanceledException: The operation was canceled.
   at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
   at System.IO.Pipes.NamedPipeServerStream.EndWaitForConnection(IAsyncResult asyncResult)
   at Common.PipeCommunication.SomePipeServer.ClientConnected(IAsyncResult ar) in SomePipeServer.cs:line 80

Эта ошибка возникает, когда я запускаю службу, даже не пытаясь подключить к ней клиент. Вот мой класс PipeServer:

public class SomePipeServer
{

    #region PRIVATE VARIABLES
    private string                  _pipeName = "SomePipeServer";
    private NamedPipeServerStream   _pipeServer;
    private IAsyncResult            _connectRequest;
    private byte[] oBuffer;  
    #endregion


    #region PUBLIC VARIABLES
    public event EventHandler MsgReceived;
    #endregion


    #region PUBLIC METHODS
    public SomePipeServer()
    {
        oBuffer = new byte[4096]; 
    }

    public void Start() 
    {
        try
        {
            _pipeServer = new NamedPipeServerStream(
                _pipeName, PipeDirection.InOut, -1,
                PipeTransmissionMode.Message,
                PipeOptions.Asynchronous);

            _connectRequest = _pipeServer.BeginWaitForConnection(
                ClientConnected, null);
        }
        catch (Exception ex)
        {
            ...
        }
    }
    public void Stop()
    {
        try
        {
            _connectRequest = null;

            if (_pipeServer == null)
                return;

            if (_pipeServer.IsConnected)
                _pipeServer.Disconnect();

            //_pipeServer.Close();
        }
        catch (Exception ex)
        {
            ...
        }
    }
    #endregion


    #region PRIVATE METHODS
    private void ClientConnected(IAsyncResult ar)
    {
        try
        {
            if (ar != null)
            {
                _pipeServer.EndWaitForConnection(ar); //line 80
                _connectRequest = null;
                _connectRequest = _pipeServer.BeginRead(oBuffer, 0, 4096,
                    ClientMessage, null);

            }
        }
        catch (Exception ex)
        {
            ...
        }
    }
    private void ClientMessage(IAsyncResult ar)
    {
        try
        {
            if (ar != null)
            {
                _pipeServer.EndRead(ar);

                string message = System.Text.ASCIIEncoding.ASCII.GetString(oBuffer).Trim(new char[] { '\0', ' ' });
                message = message.Replace(Environment.NewLine, " ").TrimEnd();

                OnReceive(message);

                _connectRequest = null;
                //_connectRequest = _pipeServer.BeginRead(oBuffer, 0, 4096,
                //    new AsyncCallback(ClientMessage), null);

                //_pipeServer.Disconnect();
                //_pipeServer.BeginWaitForConnection(ClientConnected, null);
                Stop();
                Start();
            }
        }
        catch (Exception ex)
        {
            ...
        }
    }
    private void OnReceive(string in_msg)
    {
        if (MsgReceived != null)
        {
            MsgReceived(in_msg, EventArgs.Empty);
        }
    }
    #endregion
}

1 Ответ

0 голосов
/ 04 ноября 2011

На этой странице MSDN есть обсуждение *1002* о (как я понял) той же проблеме, что и у вас.

Windows завершит все перекрывающиеся операции ввода-вывода для завершившегося потока с ERROR_OPERATION_ABORTED.

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

В этом случае я бы порекомендовал вашей основной теме создать именованные трубы; это нормально для сервера именованных каналов (с отдельным нить просто для создания именованных каналов нет).

...