0

この同じコードについて別の質問があり、クライアントがパイプを閉じた後もパイプを開いたままにします

しかし、ここでアプリを正常に終了する際に問題があります。私の主なコードは以下です。2つの問題があります。1) Thread.Abort を使用しており、2) このアプリケーションは実際には終了しません。ブレークポイントを設定すると、abort が呼び出されて終了ブレースにステップするのを確認できますが、IDE はまだデバッグ モードであり、プロセスは (プロセス マネージャーで) まだ生きています。これを適切に終了するにはどうすればよいですか?

[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");
}
4

3 に答える 3

0

作業が完了したら、ThreadStartServer メソッドから「戻る」必要があります。これを Main メソッドの Join() と組み合わせると、ワーカー スレッドは正常に終了します。さらに、BackGround スレッドにします。次に例を示します (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;

        } 
    }
}
于 2009-11-06T22:43:12.930 に答える
0

あなたが示唆するように... Thread.Abortを使用しないでください。他のオプションが機能しない非常に説得力のある理由がない限り、それは悪い考えです。

問題は、ReadLine への呼び出しをブロックしていることです。そのため、代わりに StreamReader.Peek/Read を使用して、名前付きパイプからデータを取得します。これにより、ループ内のフラグをチェックして終了できるようになります。

より複雑なソリューションについては、非同期 I/O を使用できます。いくつかの指針については、この質問を参照してください。

于 2009-11-06T21:00:30.753 に答える