【问题标题】:Must i abort this thread? Waiting for namedpipes. How do i do this properly?我必须中止这个线程吗?等待命名管道。我该如何正确地做到这一点?
【发布时间】:2009-11-06 20:38:19
【问题描述】:

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

但是在这里我遇到了优雅地终止我的应用程序的问题。我的主要代码如下。有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");
}

【问题讨论】:

    标签: c# .net multithreading named-pipes termination


    【解决方案1】:

    关于 MS 文档中的 Thread.Abort ...“调用此方法通常会终止线程。” 此外,“不能保证线程立即或完全中止。”

    我怀疑 WaitForConnection 阻止它接收线程中止。一般来说,线程中止被认为是邪恶的,因为谁知道你可以把东西留在什么状态等等。更多帮助请参见这里...http://www.interact-sw.co.uk/iangblog/2004/11/12/cancellation

    【讨论】:

      【解决方案2】:

      正如你所建议的......不要使用 Thread.Abort。除非您有一个非常令人信服的理由说明没有其他选择可行,否则这是一个坏主意。

      问题是对 ReadLine 的阻塞调用...所以改为使用 StreamReader.Peek/Read 从命名管道中提取数据。这将允许您检查循环中的标志,以便您可以退出。

      对于更复杂的解决方案,您可以使用异步 I/O ... 请参阅此 question 以获得一些指示。

      【讨论】:

      • 其实没有,问题是 pipeStream.WaitForConnection() 被阻塞了。而那个问题用它来所以它没有帮助。
      • 你的权利当然……没有仔细阅读。为什么不考虑使用 BeginWaitForConnection 以便不在那里使用阻塞调用。
      【解决方案3】:

      您需要在 ThreadStartServer 方法完成工作后“返回”它。如果将此与 Main 方法中的 Join() 结合使用,工作线程将优雅地完成。另外使其成为背景线程。这是一个示例(没有 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;
      
              } 
          }
      }
      

      【讨论】:

      • 问题是阻塞 WaitForConnection()。不是如何从线程返回。
      • 如果你移除 Join() 并让你成为工作线程后台,它会在主线程终止时优雅地退出,
      猜你喜欢
      • 1970-01-01
      • 2019-05-18
      • 2020-02-16
      • 2019-01-24
      • 1970-01-01
      • 2011-05-26
      • 2012-12-12
      • 1970-01-01
      • 2020-05-13
      相关资源
      最近更新 更多