0

我正在尝试为命名管道流编写一个示例 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函数,问题就会得到解决。为什么线程对进程间管道通信有这样的影响?

4

1 回答 1

1

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

尝试:

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

Conversation.Join();阻止调用线程执行,直到线程对象终止参见MSDN上的Thread.Join 方法Thread.IsBackground 属性

于 2014-10-29T20:22:22.793 回答