-1

In the following code

namespace ns
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string ProcessCommand(string cmd)
        {
            return "i got " + cmd;
        }

        StreamReader d_sr;
        StreamWriter d_sw;
        NamedPipeServerStream d_pipe;
        IAsyncResult d_ar;

        void Connected(IAsyncResult ar)
        {
            d_pipe.EndWaitForConnection(ar);
            d_sw.AutoFlush = true;
            while (true)
            {
                var cmd = d_sr.ReadLine();
                if (cmd == null)
                    break;
                var answer = ProcessCommand(cmd);
                d_sw.WriteLine(answer);
            }
            d_pipe.Disconnect();
            d_ar = d_pipe.BeginWaitForConnection(Connected, null);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            d_pipe = new NamedPipeServerStream("vatm", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
            d_sr = new StreamReader(d_pipe);
            d_sw = new StreamWriter(d_pipe);
            d_ar = d_pipe.BeginWaitForConnection(Connected, null);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            d_pipe.EndWaitForConnection(d_ar);
            d_pipe.Dispose();
        }
    }
}

when I go to close the form, it waits in EndWaitForConnection. I'm going to tell the pipe not to wait for client anymore and abort. I tried d_pipe.Close() instead of calling EndWaitForConnection, but I get this exception at EndWaitForConnection called in Connected.

An unhandled exception of type 'System.ObjectDisposedException' occurred in System.Core.dll Additional information: Cannot access a closed pipe.

Any idea?

I changed it to this:

namespace ns
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string ProcessCommand(string cmd)
        {
            return "i got " + cmd;
        }

        StreamReader d_sr;
        StreamWriter d_sw;
        NamedPipeServerStream d_pipe;
        IAsyncResult d_ar;

        void Connected(IAsyncResult ar)
        {
            try
            {
                d_pipe.EndWaitForConnection(ar);
                d_sw.AutoFlush = true;
                while (true)
                {
                    var cmd = d_sr.ReadLine();
                    if (cmd == null)
                        break;
                    var answer = ProcessCommand(cmd);
                    d_sw.WriteLine(answer);
                }
                d_pipe.Disconnect();
                d_ar = d_pipe.BeginWaitForConnection(Connected, null);
            }
            catch (System.ObjectDisposedException)
            {
                // do nothing
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            d_pipe = new NamedPipeServerStream("vatm", PipeDirection.InOut, 1, PipeTransmissionMode.Message, PipeOptions.Asynchronous);
            d_sr = new StreamReader(d_pipe);
            d_sw = new StreamWriter(d_pipe);
            d_ar = d_pipe.BeginWaitForConnection(Connected, null);
        }

        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            d_pipe.Close();
        }
    }
}
hamidi
  • 1,611
  • 1
  • 15
  • 28
  • Closing the waiting pipe is, as far as I know, the usual way to abort the wait. There's no other API to do that, and it's consistent with what one needs to do with the `Socket` class and an "accept" operation. Do you actually have a specific problem with using that method? – Peter Duniho Jul 25 '17 at 21:27
  • i described. i get exception. – hamidi Jul 27 '17 at 07:44
  • don't mark it as duplicate or give me the link. – hamidi Jul 27 '17 at 07:44
  • _"i described. i get exception"_ -- a description of a _normal_ exception is _not_ a **problem description**. – Peter Duniho Jul 27 '17 at 08:14
  • the problem is that i get the exception i completely gave its description. this is the problem. i don't know how to avoid it and why is that. then, again, u didn't give me what is the duplicate post. – hamidi Jul 27 '17 at 09:17
  • _"this is the problem"_ -- no, it's not a problem. And the marked duplicate explains why. Closing the pipe and handling the exception is exactly what _should_ be happening. **It's not a problem**. – Peter Duniho Jul 27 '17 at 16:13
  • handling the exception and doing nothing in the handler seems to be a workaround. a good code doesn't cause an exception, isn't it? – hamidi Jul 29 '17 at 03:24
  • _"doing nothing in the handler seems to be a workaround"_ -- don't do nothing in the handler. _Handle_ the exception. By closing the object, you are asynchronously requesting to interrupt the operation. Your exception handler is the other half of that request. It's where you need to finish cleaning up after the operation has in fact been interrupted (you don't want to clean up before it has, because you could be racing with code that's actually dealing with a completed operation). – Peter Duniho Jul 29 '17 at 03:26
  • I updated the question with the new code which includes the modifications. Please review it and let me know whether you meant this and whether the changes are made as you suggested. – hamidi Jul 30 '17 at 10:49

1 Answers1

-1

Switch to the asynchronous version: BeginWaitForConnection.

If it does ever complete, you'll need a flag so the completion handler can just call EndWaitForConnection absorbing any exceptions and exiting (call End... to ensure any resources are able to be cleaned up). enter link description here

check this

Community
  • 1
  • 1