3

私は2つのスレッドを持っています。1 つのスレッドが要求を読み取り、メッセージ キューを使用してそれをサーバーに渡し、別のスレッドがメッセージ キューから応答を読み取って送り返します。同じプロセスで、呼び出し元クラスのメソッドはパイプに要求を書き込み (最初のスレッドが共有するサーバー パイプ ストリームを使用)、次に、2 番目のスレッドが共有するクライアント パイプ ストリームを使用して応答を読み取ります。これは、次のように Java PipeInputStream と PipeOutputStream を使用して簡単に実行できます。基本的に、C# で次の Java ロジックに相当するものを探しています。C# で匿名パイプを使用しようとして失敗しました。

RequestHandlerThread (前述の Thread1)

out = new PipedOutputStream();
readPipeIs = new PipedInputStream(out);
readDataIs = new DataInputStream(readPipeIs);
// read data from readDataIs
// Send it to server over message queue
// Share 'out' so that other class method can write to it. 

応答ハンドラ (前述のスレッド 2)

in = new PipedInputStream();
writePipeOs = new PipedOutputStream(in);
writeDataOs = new DataOutputStream(writePipeOs);

// Wait and read from message queue
// write received data to 'writeDataOs'
// Share 'in' so that other class method can read from it. 

C# パイプが 2 つのプロセス間の通信に制限されているかどうかはわかりません。上記のロジックはすべて、メッセージ サーバーと通信するスレッドが 2 つあるという点だけで同じプロセスにあります。

両方のスレッドで AnonymousPipeServerStream と AnonymousPipeClientStream のペアのペアを試しました。書き込み用のサーバー ストリームと読み取り用のクライアント ストリームを別のクラス メソッドで共有しました。

上記のロジックに明らかな欠陥があるか、または IPC の選択に関する提案はありますか?

ソースコードの追加 ここに Test クラスがあります

class Test
{
    private static byte[] ret;
    private static bool ready;

    Stream outStream;
    Stream inStream;


    private void clientConnReqHandler()
    {
        AnonymousPipeServerStream pipeServer = new
              AnonymousPipeServerStream(PipeDirection.Out);

        outStream = pipeServer;

        string pipeHandle = 
                     pipeServer.GetClientHandleAsString();

        AnonymousPipeClientStream pipeClient =
            new AnonymousPipeClientStream(PipeDirection.In, 
                       pipeHandle);

        pipeServer.DisposeLocalCopyOfClientHandle();

        ready = false;
        BinaryReader binReader = new BinaryReader(pipeClient);
        int mesgSize = binReader.ReadInt32();
        System.Console.WriteLine("Message Lenght To read: " + 
                                  mesgSize);
        byte[] buffer = binReader.ReadBytes(mesgSize);
        System.Console.WriteLine("Message read: " + 
                    buffer.ToString());
        // Simulate some processing 
        Thread.Sleep(5000);
        mesgProcessing(buffer);

    }
    private static void mesgProcessing(byte[] buffer)
    {

        System.Text.UTF8Encoding encoding = new 
                            System.Text.UTF8Encoding();
        byte[] extra = encoding.GetBytes("Echo : ");

        ret = new byte[buffer.Length + extra.Length];
        System.Buffer.BlockCopy(extra, 0, ret, 0, extra.Length);
        System.Buffer.BlockCopy(buffer, 0, ret, extra.Length, 
                                buffer.Length);
        ready = true;
    }


    private void clientConnRespHandler()
    {
        AnonymousPipeServerStream pipeServer = new 
                AnonymousPipeServerStream(PipeDirection.Out);

        string pipeHandle = 
                  pipeServer.GetClientHandleAsString();

        AnonymousPipeClientStream pipeClient =
            new AnonymousPipeClientStream(PipeDirection.In, 
                  pipeHandle);

        inStream = pipeClient;
        pipeServer.DisposeLocalCopyOfClientHandle();

        while (ready)
        {
            BinaryWriter binWriter = new 
                           BinaryWriter(pipeServer);
            binWriter.Write(ret.Length);
            binWriter.Write(ret);
            ready = false;
        }
    }

    public static void Main()
    {
        Test setup = new Test();
        setup.threadTest();

        Test2 threadTest = new Test2();
        // This method will do actuall read and write. 
        threadTest.runTest(setup.inStream, setup.outStream);
    }
    public void threadTest()
    {
        Thread reqHandlerThread = new Thread(new 
                ThreadStart(clientConnReqHandler));
        Thread respHandlerThread = new Thread(new 
               ThreadStart(clientConnRespHandler));

        reqHandlerThread.Start();
        respHandlerThread.Start();

    }
}

読み取り/書き込みを行うクラス:

class Test2
{

    internal void runTest(System.IO.Stream inStream, 
                  System.IO.Stream outStream)
    {
        BinaryWriter writer = new BinaryWriter(outStream);

        System.Text.UTF8Encoding encoding = new 
                 System.Text.UTF8Encoding();
        byte[] mesg = encoding.GetBytes("Hello World!!!");

        writer.Write(mesg.Length);
        writer.Write(mesg);

        BinaryReader reader = new BinaryReader(inStream);
        int mesgSize = reader.ReadInt32();
        System.Console.WriteLine("Message Lenght To read: " + 
                      mesgSize);
        byte[] buffer = reader.ReadBytes(mesgSize);
        System.Console.WriteLine("Message read: " + 
                    buffer.ToString());
    }
}

ありがとう

4

1 に答える 1

0

わかった。DisposeLocalCopyOfClientHandle() を削除した後に機能しました。もちろん、while ループ条件の new-by ミスを修正して、データの準備ができているかどうかを確認し、バイト配列から文字列を正しく出力する必要がありました。

于 2012-04-17T02:28:23.773 に答える