乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      C#各種結(jié)束進(jìn)程的方法詳細(xì)介紹

       kittywei 2015-09-09

      C#各種結(jié)束進(jìn)程的方法詳細(xì)介紹

      Process類的CloseMainWindow, Kill, Close

      Process.CloseMainWindow是GUI程序的最友好結(jié)束方式,從名字上就可以看出來它是通過結(jié)束主窗體,相當(dāng)于用戶點(diǎn)擊窗體的關(guān)閉按鈕或者按Alt + F4。它的本質(zhì)就是向主窗體發(fā)送WM_CLOSE消息(Process.MainWindowsHandle可以返回主窗體的句柄)。這個(gè)可以在.NET Framework源代碼中看出來:

      publicbool CloseMainWindow()

      {

      IntPtr mainWindowHandle =this.MainWindowHandle;

      //句柄是否為0

      if (mainWindowHandle ==IntPtr.Zero)

      {

      returnfalse;

      }

      //GetWindowLong是否成功執(zhí)行

      if ((NativeMethods.GetWindowLong(newHandleRef(this, mainWindowHandle), -16) &0x8000000) !=0)

      {

      returnfalse;

      }

      //0x10 是 WM_CLOSE消息

      //向主窗體發(fā)送WM_CLOSE,注意是PostMessage而不是SendMessage

      NativeMethods.PostMessage(newHandleRef(this, mainWindowHandle), 0x10, IntPtr.Zero, IntPtr.Zero);

      returntrue;

      }

       

      CloseMainWindow方法使用PostMessage(不是SendMessage,所以消息會(huì)加在消息隊(duì)列的最后)方法向主窗體發(fā)送一個(gè)WM_CLOSE消息,這樣等主窗體處理完所有消息后,等遇到WM_CLOSE便開始執(zhí)行退出動(dòng)作。

      比如記事本接到了WM_CLOSE消息但是有未保存的文件記事本會(huì)彈出對(duì)話框提示用戶保存還是不保存還是取消退出操作。Windows Forms和WPF的窗體都會(huì)有類似操作,通過窗體的Closing事件來在WM_CLOSE消息接收后做出是否退出的決定。

       

      之后我們會(huì)講到Windows Forms和WPF都有自己的友好型常規(guī)退出方式,但是其實(shí)有一個(gè)通用的GUI程序退出方式,就是利用這個(gè)CloseMainWindow方法:

      //Windows Forms和WPF都可以用

      //Windows Forms的Form.Closing事件會(huì)在之后發(fā)生

      //WPF的Windows.Closing事件也會(huì)

      Process.GetCurrentProcess().CloseMainWindow();

       

       

       

      接下來就是Process.Kill方法,從名字也可以看出來,直接殺掉,不給喘息喘息機(jī)會(huì)呵呵。Kill方法會(huì)直接結(jié)束整個(gè)進(jìn)程,不進(jìn)行常規(guī)資源清理(什么finally塊等……)。Kill本質(zhì)調(diào)用本地API:TerminateProcess函數(shù)。

       

       

      最后一個(gè)是Process.Close方法。抱歉它根本不是用來結(jié)束進(jìn)程的!這個(gè)方法名字有些誤導(dǎo),其實(shí)根本則不然。它僅僅是而是IDisposable的Dispose方法的具體執(zhí)行,用來進(jìn)行Process類的托管資源清理的!

      由于Process類繼承自Component類,后者繼承IDisposable而同時(shí)又有析構(gòu)函數(shù),而通過一個(gè)繼承類可改寫的Dispose方法(參數(shù)是bool disposing)來判斷這個(gè)Dispose是用戶調(diào)用還是GC調(diào)用。而這個(gè)Process.Close()方法正是用戶調(diào)用Dispose時(shí)進(jìn)行托管資源的清理方法:

      下面Process.Dispose方法代碼:

      protectedoverridevoid Dispose(bool disposing)

      {

      if (!this.disposed)

      {

      if (disposing)

      {

      //用戶調(diào)用,清理托管資源

      this.Close();

      }

      this.disposed =true;

      //調(diào)用Component的Dispose

      base.Dispose(disposing);

      }

      }

       

      這個(gè)Close方法類似很多其他.NET中的類,比如Stream……因此Close肯定不會(huì)結(jié)束進(jìn)程,僅僅是Process類作為IDisposable接口的間接繼承者的自我清理方法。

       

       

       

      Environment類的Exit和FailFast

      Environment.Exit相當(dāng)于在Main函數(shù)中的return指令。不過它不會(huì)執(zhí)行代碼塊的finally塊(如果有的話),但資源清理還是要進(jìn)行的。

       

      它是最常見的退出當(dāng)前進(jìn)程的方法之一。在Main函數(shù)中我們可以直接return語句便退出了程序。如果不在Main函數(shù)內(nèi),那么Environment.Exit方法就可以派上用場(chǎng):

      classa

      {

      ~a()

      {

      Console.WriteLine("析構(gòu)函數(shù)");

      }

      }

      classProgram

      {

      staticvoid Main()

      {

      try

      {

      a oa =newa();

      test();

      }

      finally

      {

      //這段代碼永遠(yuǎn)不會(huì)執(zhí)行

      Console.WriteLine("finally");

      }

      }

       

      staticvoid test()

      {

      Environment.Exit(0);

      }

      }

       

      代碼將會(huì)輸出:

      析構(gòu)函數(shù)

      看來GC調(diào)用了oa的析構(gòu)函數(shù),但注意finally塊沒有運(yùn)行。

       

       

      Environment.FailFast方法更速度,它甚至不需要向操作系統(tǒng)返回進(jìn)程退出代碼(ExitCode),直接結(jié)束當(dāng)前進(jìn)程并在應(yīng)用程序事件薄中寫入信息,用于程序出現(xiàn)致命錯(cuò)誤需要立即停止。

      classa

      {

      ~a()

      {

      Console.WriteLine("析構(gòu)函數(shù)");

      }

      }

      classProgram

      {

      staticvoid Main()

      {

      try

      {

      a oa =newa();

      Environment.FailFast("致命錯(cuò)誤發(fā)生!");

      }

      finally

      {

      //這段代碼永遠(yuǎn)不會(huì)執(zhí)行

      Console.WriteLine("finally");

      }

      }

      }

       

      在.NET 4.0下,Environment.FailFast代碼會(huì)拋出FatalExecutionEngineError,而在4.0之前會(huì)拋出ExecutionEngineException。但都不會(huì)有任何輸出(GC沒有清理對(duì)象,同時(shí)finally塊也沒有運(yùn)行)

       

       

       

       

      WPF的Shutdown和Windows Forms的Exit

      GUI程序往往都有自己的消息隊(duì)列和事件管理模式,因此結(jié)束一個(gè)GUI程序要遠(yuǎn)復(fù)雜與結(jié)束一個(gè)控制臺(tái)程序。上述的方法中,Process.Kill和Environment.Exit和FailFast如果用在一個(gè)GUI程序中,都會(huì)直接強(qiáng)制結(jié)束整個(gè)程序,而不會(huì)激發(fā)GUI窗體的一些針對(duì)應(yīng)用程序結(jié)束的事件(比如Closing事件)。而上面也講過:Process.CloseMainWindow通過向主窗體發(fā)送一個(gè)WM_CLOSE消息可以很好的結(jié)束一個(gè)GUI程序,不過往往更自然的方法是利用GUI框架本身提供的結(jié)束程序的方法。

       

      WPF中是System.Windows.Application.Shutdown方法,它其實(shí)就是在當(dāng)前線程的消息隊(duì)列Dispatcher對(duì)象中加入一個(gè)正常優(yōu)先級(jí)(DispatcherPriority.Normal)的回調(diào)退出函數(shù),等消息隊(duì)列最后處理到該項(xiàng)時(shí)程序開始退出操作。通常這樣使用:

      //或者App也可以,WPF程序默認(rèn)會(huì)有一個(gè)App類繼承Application類

      Application.Current.Shutdown();

       

       

      Windows Forms中是:System.Windows.Forms.Application.Exit方法。它是通過Application.OpenFormsInternal屬性先把已經(jīng)打開的窗體通過正常方式都關(guān)閉(運(yùn)行Form.Closing事件),最后再結(jié)束整個(gè)應(yīng)用程序進(jìn)程。

       

      而且通過WPF的Window.Closing或Windows Forms的Form.Closing事件都可以取消這種形式的退出操作。

       

       

       

      非托管的ExitProcess和TerminateProcess

      這是Windows API中結(jié)束進(jìn)程的非托管方法。ExitProcess結(jié)束進(jìn)程更友好些,而TerminateProcess會(huì)立即強(qiáng)制結(jié)束進(jìn)程。兩者的關(guān)系有點(diǎn)像Environment.Exit和FailFast,但我不確定本質(zhì)上是否一樣。而且TerminateProcess可以指定進(jìn)程返回值,但FailFast不可以。兩個(gè)非托管API的執(zhí)行都不回運(yùn)行finally塊。

      使用起來很簡(jiǎn)單(關(guān)鍵是P/Invoke,參考:http://www.,很有用的)

      using System.Runtime.InteropServices;

      classProgram

      {

      [DllImport("kernel32.dll")]

      staticexternvoid ExitProcess(uint uExitCode);

       

      [DllImport("kernel32.dll", SetLastError =true)]

      [return: MarshalAs(UnmanagedType.Bool)]

      staticexternbool TerminateProcess(IntPtr hProcess, uint uExitCode);

       

      staticvoid Main()

      {

      ExitProcess(1);

      //或者

      TerminateProcess(Process.GetCurrentProcess().Handle, 1);

      }

      }

       

       

       

       

      手動(dòng)發(fā)送WM_CLOSE,WM_DESTROY,WM_QUIT消息

      在一個(gè)GUI程序運(yùn)行環(huán)境下,我們通過得到窗體的句柄,然后便可以向該句柄發(fā)送消息,WndProc(Window Procedure)函數(shù)會(huì)處理相應(yīng)的事件。其中WM_CLOSE相當(dāng)于用戶點(diǎn)擊關(guān)閉按鈕,使用PostMessage將WM_CLOSE發(fā)送至主窗體等價(jià)于.NET中Process類的CloseMainWindow方法,當(dāng)接收到WM_CLOSE消息時(shí),應(yīng)用程序是可以選擇是否真正結(jié)束程序的,如果繼續(xù)結(jié)束程序而不取消。接著WM_DESTROY消息會(huì)發(fā)送,這個(gè)消息代表著窗體開始真正關(guān)閉,此時(shí)可以進(jìn)行一些資源的清理。最后當(dāng)前線程接收到WM_QUIT消息,線程的消息循環(huán)會(huì)被終止。

       

      因此向窗體發(fā)送這3個(gè)消息,只有WM_CLOSE會(huì)引發(fā)Closing事件,屬于正常窗體退出邏輯,其他兩個(gè)中消息會(huì)直接強(qiáng)行關(guān)閉窗體。

      注意WM_QUIT消息只能用PostMessage將其送至消息隊(duì)列尾部,使用SendMessage立即發(fā)送在WPF應(yīng)用程序上運(yùn)行后程序沒有任何反應(yīng)。

       

      下面是一個(gè)WPF程序發(fā)送下列消息,(并沒有貼XAML,你一定知道怎樣加3個(gè)按鈕然后把Click事件和窗體的Closing事件綁在代碼上吧)

      using System;

      using System.Collections.Generic;

      using System.Linq;

      using System.Text;

      using System.Windows;

      using System.Windows.Controls;

      using System.Windows.Data;

      using System.Windows.Documents;

      using System.Windows.Input;

      using System.Windows.Media;

      using System.Windows.Media.Imaging;

      using System.Windows.Navigation;

      using System.Windows.Shapes;

      //外加命名空間

      using System.Diagnostics;

      using System.Runtime.InteropServices;

       

      namespace Mgen.TEX

      {

      publicpartialclassMainWindow : Window

      {

      public MainWindow()

      {

      InitializeComponent();

      }

       

      //Windows消息值

      constuint WM_CLOSE =0x10;

      constuint WM_DESTROY =0x02;

      constuint WM_QUIT =0x12;

       

      //SendMessage和PostMessage的P/Invoke

      [DllImport("user32.dll", CharSet =CharSet.Auto)]

      staticexternIntPtr SendMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

       

      [return: MarshalAs(UnmanagedType.Bool)]

      [DllImport("user32.dll", SetLastError =true)]

      staticexternbool PostMessage(IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

       

      //窗體的Closing事件,判斷Closing是否被運(yùn)行

      privatevoid Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)

      {

      MessageBox.Show("Closing事件!");

      }

       

      //發(fā)送三種消息

      privatevoid WM_CLOSE_Click(object sender, RoutedEventArgs e)

      {

      //也可以用PostMessage

      SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_CLOSE, IntPtr.Zero, IntPtr.Zero);

      }

       

      privatevoid WM_DESTROY_Click(object sender, RoutedEventArgs e)

      {

      //也可以用PostMessage

      SendMessage(Process.GetCurrentProcess().MainWindowHandle, WM_DESTROY, IntPtr.Zero, IntPtr.Zero);

      }

       

      privatevoid WM_QUIT_Click(object sender, RoutedEventArgs e)

      {

      //只能使用PostMessage去將WM_QUIT送至消息隊(duì)列尾部

      PostMessage(Process.GetCurrentProcess().MainWindowHandle, WM_QUIT, IntPtr.Zero, IntPtr.Zero);

      }

       

      }

      }

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多