假设程序主线程是s1,在主线程上派生的线程是s2。现在有这么一个问题:当s2正在执行时,s1接到外部消息说本程序需要结束,那么s1如何通知s2这个消息? 然后s1要等待s2把自己的善后做完以后才能kill掉s2,然后结束整个程序。当然了,s2处理完自己的善后还要通知s1:你可以kill我了。

解决方案 »

  1.   

    用线程的Join()方法。用法为:阻塞调用线程,直到某个线程终止时为止。
      

  2.   

    定义一个两个线程都可以访问的bool类型变量,如果让s2停止,在s1中将这个bool类型赋值成true,当s2判断为true时,进行后续收尾工作!!!
      

  3.   

    to :当s2正在执行时,s1接到外部消息说本程序需要结束,那么s1如何通知s2这个消息?可以用函数,接到外部消息后,执行如下的函数:
    private void DelThread()
    {
    s2.join(); //等待s2结束后才往下执行。
    // do your other code;
    this.dispose();
    }
      

  4.   

    tjvictor(初学者) ,你所说的好像可以解决“s1如何通知s2这个消息”的问题,但是正在工作的s2怎么获得这个消息呢?s2获得到了这个消息,才开始自己的扫尾工作。还有 ,
    private void DelThread()
    {
    s2.join(); //等待s2结束后才往下执行。
    // do your other code;
    this.dispose();
    }
    这里的"等待s2结束后才往下执行。",什么叫做s2结束?他自己杀死自己吗?
      

  5.   

    fangxiangting() ,谢谢你的建议,我想问一下,有没有更好的方法,例如.net本身有没有提供什么线程之间通信的,例如ManualResetEvent,应该怎么用? 最好能有个例子。
      

  6.   

    Thread s2 = new Thread ( new ThreadStart ( ttt ) );
    s2.start();private void ttt ()
    {
       \\fo your work;
    }线程开始于s2.start;
    终止于ttt()完成。如果ttt中有循环,例如:
    private void ttt()
    {
    while ( true )
    {
        //侦测某一个端口;
    }
    }这样的话,s2才会一直执行下去,除非强行结束。
    也就是说,在外部(例如s1中)执行:s2.abort();
      

  7.   

    实现方法应该很多吧,同步互斥之类的,.net都支持的
      

  8.   

    ManualResetEvent用于线程之间的互斥的。相当于一个“锁”的作用一样。线程之间的通信,如果两个线程在同一个form中的话,可以用全局变量。
      

  9.   

    s1 通知 s2 结束  
       在s1的函数中使用 s2.Abort();
       然后使用    s1.Join()等待系统通知s2已经结束s2.Abort会引发一个异常,一般可以在 catch 中捕获该特定类型的异常,进行善后
      

  10.   

    多练练吧Thread类提供的各种方法
      

  11.   

    多谢各位大哥的建议,小弟就是在做SOCKET的服务端,但没有采用.NET自身提供的异步机制,而是自己创建线程,来实现“多客户端”、“长连接”,以下是代码,各位看看应该怎么样来安全地关闭程序:
    private void button1_Click(object sender, System.EventArgs e)
    {
    //启动监听线程
    Iprocessor = new Thread(new ThreadStart(Listening));
    Iprocessor.Start();
    }
    //侦听
    private void Listening()
    {
    listener = new TcpListener(InPort); try
    {
    listener.Start();
    }
    catch(Exception ex)
    {
    WriteTextLog(strLogFile,"无法打开端口" + ex.Message);
    } while(Iprocessor.IsAlive)
    {
    try
            {
        sAccepted = listener.AcceptSocket();              //接受挂起的连接请求,返回一个SOCKET对象                      //启动接收线程
        Iclientservice = new Thread(new ThreadStart(IServiceClient));     Iclientservice.Start();
    }
    catch(Exception ex)
    {

    if(Iclientservice.IsAlive)
    {
    Iclientservice.Abort();
    }
    break;
    }
    }//end while
    }//接收和处理以及发送报文
    private void IServiceClient()
    {
           while(sAccepted.Connected)//只要客户端没有断开,就一直处理来自她的消息----实现所谓的“长连接”
           {
                   try
         {
                      if(sAccepted.Available != 0)//有数据可接收
                      {
                           //业务处理
                      }
                      else
                      {
                              Thread.Sleep(30000);//阻塞当前线程30秒,以避免这个死循环一直在走而占用CPU
                      }
                            
                  }
                  catch(Exception ex)
        {}       }//end while       //既然客户端已经断开,那么就关闭这个socket
           sAccepted.Shutdown(SocketShutdown.Both);
           sAccepted.Close();
    }
      

  12.   

    class ..private bool Cancel_IServiceClient = false;  //设置一个标识在取消按钮按下设置 = true;while(sAccepted.Connected && !Cancel_IServiceClient) //如果需要取消线程, 先修改标识退出这个循环,自然取消,不过这里有一个 Thread.Sleep(30000); 可能要等30秒线程才会结束
    {}上面的方法适合一次取消所有线程如果只取消某个, 则需要对线程编号 ,然后分别private bool [] Cancel_IServiceClient,
     定义一个标识数组.更科学的方法是继承一个线程类,然后直接对该类的实例操作
      

  13.   

    使用delegate,
    请大家关心我的问题。
    我一直在VS2003看不到错误(或异常)对话框。当我的程序经过(throw new exception)时,只是退出,没有
    错误(或异常)对话框弹出或者在输出终端输出错误细节,NullReferenceException 和数组边界溢出一样,没有错误(或异常)对话框弹出或者在输出终端输出错误细节。这搞得我不知道哪儿出错,可费劲了。最后我不得不用 Debug.assert去代替所有的Exception。
    有没有那位网友遇到同样的现象?谢谢了。
      

  14.   

    这是多线程编程里面的一个经典问题,正确的方法就是采用
    bool 类型的全局变量,子线程的循环条件先判断该全局变量
    是否为true,当主线程要结束时,把该变量设为false。
    当然该共享变量需要用互斥体保护起来(JAVA 里面似乎不用)。
      

  15.   

    你这个server好像只联了一个client,对吗?
    要是这样的话,就不用这么麻烦了,用bool判断一下就行了。
      

  16.   

    各位大哥,不幸的是,领导不同意这样的做法:
    1,不想用sleep(30000)--我原来用这个是怕while()循环占用cpu太厉害;他的意思是说把sleep(30000)修改为等待一个消息----一旦这个连接上有下一条消息来了,就马上去处理,否则一直在这里等。2,不同意用置位全局变量的方式通知子线程。
      

  17.   

    to tjvictor(初学者) ,我这个是多client的,只不过前边等待连接的那部分代码我没有贴,等到一个连接,便起一个线程,在这个线程里处理这个client的一切...
      

  18.   

    我汗到死,你直接去Abort子线程不就行了?如果有什么善后的工作可以写到finally或者用using哈。多看看SDK吧……
      

  19.   

    最好用异步的吧..参考一下..
    http://blog.csdn.net/yeerh/archive/2006/06/22/821797.aspx
      

  20.   

    个人也觉得长连接会使用太多线程,阻塞编程的话,可以有多种办法,在阻塞时直接abort线程可能不一定会有效,可以尝试close线程相关socket ,并且在线程处理过程内设置try ...catch..如果设置在while外,出现异常就可以退出了..