zoukankan      html  css  js  c++  java
  • 关于如何使用自定义的结束消息循环的方式 (转载)

    其实这个问题对于高手来说可能是很简单的,因为真正的实现过程并不复杂,实际上涉及到的代码也并不多,但是在没有搞清楚在.net下系统如何退出线程之前,这个问题还是困扰了我这个菜鸟很久的。

         感觉上对于一个简单的单线程的winform程序来说,好像点击了主Form的close,主线程就自动退出了。但是它是如何退出的呢?

         在查阅了MSDN和SDK之后,这个问题逐步的明朗了。

         首先一定要清楚一件事,那就是当主窗体初始化完成后当前线程在做什么,其实是在等待(等待处理新的消息):
    处理消息队列中的新消息 Application.Run();

        这一点还是很好理解的,可是如何定义退出呢?谁来负责消息循环的退出(即结束当前线程)呢?其实,Application.Run()这个方法是和另外一个类的实例配合使用的---ApplicationContext类。SDK中对这个类的解释是:指定有关应用程序线程的上下文信息。乍一听,很是迷惑。可是看过SDK提供的例子思路就清晰了很多。我对代码进行了精简,只留下了足以说明问题的部分。

    ApplicationContext的使用using System;
    using System.Windows .Forms ;
    using System.Drawing;
    using System.ComponentModel ;

    namespace ApplicationContextTest
    {
         public class AppForm1 : System.Windows .Forms .Form
         {
              public AppForm1()
             {
                   this.Size = new Size (200,200);
                  this.Text = "AppForm1";
             }
     }

     public class Test : ApplicationContext
     {
          private AppForm1 form1;
          private Test()
          {
             form1 = new AppForm1 ();
             form1.Closed += new EventHandler(OnFormClosed);

             form1.Show ();
          }
           public void OnFormClosed(object sender, EventArgs e)
           {
                ApplicationContext appContext = new ApplicationContext (form1);
                appContext.ExitThread ();
            }

      [STAThread]   
      public static void Main()
      {
            Test test = new Test ();
            Application.Run (test);
      }
     }
    }

       
        我们通过上面的代码可以看到,实际上Run()方法是有参数的,也就是所谓的线程的上下文,它的参数就是ApplicationContext类或者它的派生类。通常情况下,如果我们没有自定义ApplicationContext的派生类的话,那么默认的线程上下文就是.net提供的ApplicationContext类本身。这时候,消息循环是通过主Form的OnClosed事件来结束的(果不出我之所料,不过好像太简单了,地球人都知道... ...)。需要特别说明的一点是,其实ApplicationContext只是负责监听(监听OnClosed事件),真正负责退出消息循环的还是Application类自己。

        但是在上面的代码中我们通过构建自己的ApplicationContext类的实例(我习惯把class A的派生类叫做"自己的A类",大家明白即可),我们在类的内部重新定义了如何推出消息循环(其实就是按自己的需要重新定义退出消息循环的条件),可以看到,消息循环的退出不再是由于发生了主Fomr的OnClosed事件,而是子窗体的OnClosed事件(这里给出的条件似乎不是很典型,我们当然也可以响应其他的系统事件,来结束当前线程中的消息循环)。
        这样一来,我们就可以实现自定义当前线程的消息循环的退出条件了。我感觉这样做在某些时候应该还是很有意义的,比如对于一个应用程序,它的主窗体并没有实际的意义,真正有意义的是所有的子窗体,换句话说当所有的子窗体都close掉以后,应用程序结束。这个时候主Form的close对于我们是没有意义的,我们可以在用户点击了主Form的close之后,通过CancelEventArgs 的实例e来取消主程序的结束,并隐藏主窗体,以防止用户对主窗体进行不必要的操作。
    主窗体的处理private void MainForm_OnClosed(object sender, CancelEventArgs e)
    {
        e.Cancel  =  true;
        ((Form)sender).Hide();
    }
        当然了,对于主窗体来说如果在某些时候还需要使用的话,干脆做成系统托盘会更好一些。
        这时候,我们只需要在我们从ApplicationContext类派生出来的类中定义消息推出的条件就可以了,比如条件是子窗体的计数器为零则程序退出。(可一定要保证在程序启动的时候至少有一个子窗体呦)
        最后不要忘了在程序中将派生类进行实例化,并且将实例对象作为Run()方法的参数。
  • 相关阅读:
    Javascript 跨域知识详细介绍
    jquery对象和DOM对象的相互转换详解
    jQuery 第四章 实例方法 DOM操作之data方法
    jQuery 第四章 实例方法 DOM操作_基于jQuery对象增删改查相关方法
    jQuery 第二章 实例方法 DOM操作取赋值相关方法
    jQuery 第三章 CSS操作
    jQuery 第二章 实例方法 DOM操作选择元素相关方法
    jQuery 第一章 $()选择器
    javaScript之实战 页面筛选功能
    javaScript 二分查找
  • 原文地址:https://www.cnblogs.com/chorrysky/p/578016.html
Copyright © 2011-2022 走看看