为什么在处理间通信期间线程断开命名管道?

时间:2013-10-26 10:26:38

标签: c# pipe named-pipes interprocess

我正在尝试为命名管道流编写示例C#程序。我创建两个可执行文件,一个用于服务器,另一个用于客户端。请检查下面的代码。这两个应用程序有时可以正常工作,有时客户端应用程序在没有任何原因或异常的情况下关闭,导致服务器应用程序中的管道已损坏异我认为,在这种情况下,这些进程不同步,特别是当我在代码中加入一些延迟时,例如调试模式延迟。当服务器仍在等待 PipeDrain (pipeServer.WaitForPipeDrain())时,为什么客户端进程突然关闭?

感谢您的帮助。

服务器:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.Threading;

namespace NamedPipeServer
{
    class NamedPipeServerClass
    {
        static void Main(string[] args)
        {
            NamedPipeServerStream pipeServer = new NamedPipeServerStream("namedPipe", PipeDirection.InOut, 4);
            StreamReader SR = new StreamReader(pipeServer);
            StreamWriter SW = new StreamWriter(pipeServer);
            pipeServer.WaitForConnection();
            string temp;
            try
            {
                SW.WriteLine("Waiting");
                SW.Flush();
                pipeServer.WaitForPipeDrain();
                temp = SR.ReadLine();
                Console.WriteLine(temp + '\n');

                SW.WriteLine("Hello");
                SW.Flush();
                pipeServer.WaitForPipeDrain();
                temp = SR.ReadLine();
                Console.WriteLine(temp + '\n');

                SW.WriteLine("How are you?");
                SW.Flush();
                pipeServer.WaitForPipeDrain();
                temp = SR.ReadLine();
                Console.WriteLine(temp + '\n');

                SW.WriteLine("GoodBye");
                SW.Flush();
                pipeServer.WaitForPipeDrain();
                temp = SR.ReadLine();
                Console.WriteLine(temp + '\n');
            }

            catch (Exception ex)
            {
                throw ex;
            }

            finally
            {
                pipeServer.WaitForPipeDrain();
                if (pipeServer.IsConnected)
                {
                    pipeServer.Disconnect();
                }
            }

            Console.WriteLine("Server: Press any key to exit...");
            Console.ReadLine();
        }
    }
}

客户端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO.Pipes;
using System.IO;
using System.Threading;

namespace NamedPipeClient
{
    class NamedPipeClientClass
    {
        static NamedPipeClientStream pipeClient;
        static StreamReader SR;
        static StreamWriter SW;
        static Thread Conversation = new Thread(new ThreadStart(Con_function));
        static bool HandShake_Ok = false;

        static void Main(string[] args)
        {
            pipeClient = new NamedPipeClientStream(".", "namedPipe", PipeDirection.InOut, PipeOptions.None);
            if (pipeClient.IsConnected != true) 
            { 
                pipeClient.Connect(); 
            }
            SR = new StreamReader(pipeClient);
            SW = new StreamWriter(pipeClient);
            Conversation.Name = "ConversationThread";
            Conversation.IsBackground = true;
            Conversation.Start();
        }
        static void Con_function()
        {
            string temp;
            while (true)
            {
                try
                {
                    temp = SR.ReadLine();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                if (temp == "Waiting")
                {
                    HandShake_Ok = true;
                    try
                    {
                        SW.WriteLine("Welcome");
                        SW.Flush();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else if (HandShake_Ok && temp == "Hello")
                {
                    try
                    {
                        SW.WriteLine("Hi");
                        SW.Flush();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else if (HandShake_Ok && temp == "How are you?")
                {
                    try
                    {
                        SW.WriteLine("I am fine");
                        SW.Flush();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
                else if (HandShake_Ok && temp == "GoodBye")
                {
                    try
                    {
                        HandShake_Ok = false;
                        SW.WriteLine("Good bye :)");
                        SW.Flush();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }
            }
        }
    }
}

更新 :在客户端中,管道中的文字和读数在一个名为 Conversation 的线程中完成。如果我删除此线程并将所有文字和读数带入 Main 功能,问题将得到解决。为什么线程对进程间管道通信有这样的影响?

1 个答案:

答案 0 :(得分:1)

我相信你在这里遇到的是Conversation.IsBackground = true;,因为客户端应用程序不会在退出之前等待Conversation线程完成

尝试:

Conversation.Name = "ConversationThread";
Conversation.IsBackground = true;
Conversation.Start();
Conversation.Join();

Conversation.Join();阻止调用线程执行,直到线程对象终止 见Thread.Join Method& MSDN上的Thread.IsBackground Property