user34537
user34537

Reputation:

Must i abort this thread? Waiting for namedpipes. How do i do this properly?

I have another question about this same code and keeping the pipe open after the client closes it

But here i have a problem gracefully terminating my app. My main code is below. There are 2 problems. 1) I am using Thread.Abort and 2) This application doesnt actually end. I can set a breakpoint and see abort is called and step to the ending brace but the IDE is still in debug mode and the process is still alive (in process manager). How do i properly terminate this?

[STAThread]
static void Main(string[] args)
{
    Thread t;
    t = new Thread(new ThreadStart(ThreadStartServer));
    bool hasInstance = true;
    try
    {
        pipeStream = new NamedPipeServerStream(pipename);
        hasInstance = false;
        pipeStream.Close();
        t.Start();
        pipeStream.Dispose();
    }
    catch (System.IO.IOException)
    {
        hasInstance = true;
    }
    if (hasInstance)
    {
        clientPipeMessage(args[1]);
        return;
    }
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
    t.Abort();
}

static public void ThreadStartServer()
{
    while (true)
    {
        using (NamedPipeServerStream pipeStream = new NamedPipeServerStream(pipename))
        {
            Console.WriteLine("[Server] Pipe created {0}", pipeStream.GetHashCode());
            // Wait for a connection
            pipeStream.WaitForConnection();
            Console.WriteLine("[Server] Pipe connection established");
            using (StreamReader sr = new StreamReader(pipeStream))
            {
                string temp;
                while ((temp = sr.ReadLine()) != null)
                {
                    Console.WriteLine("{0}: {1}", DateTime.Now, temp);
                }
            }
        }
    }
    Console.WriteLine("Connection lost");
}

Upvotes: 0

Views: 1328

Answers (3)

dashton
dashton

Reputation: 2714

You need to "return" from your ThreadStartServer method when it has completed its work. If you combine this with a Join() in the Main method, the worker thread will finish gracefully. Additionally make it a BackGround thread. Here is an example (without the PipeStream):

class Prog
{
    static void Main(string[] args)
    {
        Thread t;
        t = new Thread(new ThreadStart(ThreadStartServer));
        t.IsBackground = true;
        try
        {
            t.Start();

            // time consuming work here
        }
        catch (System.IO.IOException)
        {
            // from your example
        }

        t.Join();
    }
    static public void ThreadStartServer()
    {
        while (true)
        {
            int counter=0;
            while (++counter < 10)
            {
                Console.WriteLine("working.");
                // do time consuming things
                Thread.Sleep(500);

            }
            return;

        } 
    }
}

Upvotes: 0

Rob Walker
Rob Walker

Reputation: 47462

As you suggest ... don't use Thread.Abort. Unless you have a very compelling reason why no other option will work it is a bad idea.

The problem is the blocking call to ReadLine ... so instead use StreamReader.Peek/Read to pull data from the named pipe. This will allow you to check a flag in the loop so that you can exit.

For a more complex solution you could use asynchronous I/O ... see this question for some pointers.

Upvotes: 0

Jim L
Jim L

Reputation: 2327

About Thread.Abort from MS documentation ... "Calling this method usually terminates the thread." Furthermore "The thread is not guaranteed to abort immediately, or at all."

I suspect the WaitForConnection is blocking it from receiving the thread abort. Generally speaking, thread abort is considered Evil as who knows what state you could leave things in, etc. See here for some more help...http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

Upvotes: 2

Related Questions