关于C#关闭窗体后,依旧有后台进程在运行的解决方法

话不多说直接粘贴链接,这个博主写的非常详细

http://www.cnblogs.com/HappyEDay/p/5713707.html

这里粘贴原文权当备份了。

C#中WinForm程序退出方法技巧总结 

一、关闭窗体 

在c#中退出WinForm程序包括有很多方法,如:this.Close(); Application.Exit();Application.ExitThread(); System.Environment.Exit(0); 等他们各自的方法不一样,下面我们就来详细介绍一下。 

1.this.Close();   只是关闭当前窗口,若不是主窗体的话,是无法退出程序的,另外若有托管线程(非主线程),也无法干净地退出; 

2.Application.Exit();  强制所有消息中止,退出所有的窗体,但是若有托管线程(非主线程),也无法干净地退出; 

3.Application.ExitThread(); 强制中止调用线程上的所有消息,同样面临其它线程无法正确退出的问题; 

4.System.Environment.Exit(0);   这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净。 

二、登录窗体与主窗体的关闭 

有许多人在用做c# 做登录窗体时会遇到这样的问题,登录成功后当前登录Form关闭,打开Main窗体,但Main窗体点关闭按钮后程序仍在进程仍旧在运行。 

事实上,关闭Main窗体,只是关闭了Main窗体的线程,并没有关闭程序的主线程,即程序的主线程为登录From。 

方法一:(FrmLogin 为登录窗体,FrmMain 为主窗体) //登录窗体中“登录”按钮的单击事件 

复制代码
private void button1_Click(object sender, EventArgs e)        
 { 
       if (txtName.Text == "123456")  
       { 
              FrmMain fm = new FrmMain();    
              fm.Show(); 
              this.Dispose(false);  
        }   
} 
复制代码

//主窗体的FormClosing事件或FormClosed事件代码 

private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)         

            Application.Exit();         

}  

//主窗体的FormClosed事件代码 

private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)         

            Application.Exit();         

}  

说明:FormClosing事件或FormClosed事件二选一,这两个的区别在于 FormClosed 在关闭后发生,窗体的关闭动作不可取消; 

FormClosing 在关闭前发生,可取消,只要在里面使用 e.Cancel=true; 就可以让窗口不能关闭。  

进阶技巧:在退出程序前弹出确认退出程序的对话框 //主窗体的FormClosing事件代码 

private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)         

{             

            if (MessageBox.Show("真的要退出程序吗?", "退出程序", MessageBoxButtons.OKCancel) == DialogResult.Cancel) 

            { 

                e.Cancel = true; 

            }         

主窗体的FormClosed事件代码 

private void FrmMain_FormClosed(object sender, FormClosedEventArgs e)         

            Dispose(); 

            Application.Exit();         

}  

小贴士:以下代码会导致显示确定退出的两次对话框,第一次单击“确定”第二次单击任何一个都会退出。 

private void FrmMain_FormClosing(object sender, FormClosingEventArgs e)         

{             

            if (MessageBox.Show("真的要退出程序吗?", "退出程序", MessageBoxButtons.OKCancel) == DialogResult.OK) 

            { 

                Application.Exit();

             }

             else

             { 

                e.Cancel = true;

             }         

}  

分析:第一次单击了退出对话框的“确定”按钮后,Application.Exit();会导致触发第二次FrmMain_FormClosing()事件,所以就会显示两个确认退出的对话框,但第二对话框的选择对是否退出没有影响。可以改为判断如果单击了不是确认按钮则e.Cancel = true; ,确定按钮什么都不写或不做判断,如果要加上Application.Exit(); 可以将其添加到窗体的FormClosed事件中。  方法二: 

//program.cs  程序入问的Main()方法代码,其中FrmLogin为登录窗体,FrmMain为主窗体  

static void Main()         

            Application.EnableVisualStyles(); 

            Application.SetCompatibleTextRenderingDefault(false); 

 

            FrmLogin fl = new FrmLogin(); 

            if (fl.ShowDialog() == DialogResult.OK) 

            { 

                Application.Run(new FrmMain());

             }                     

}  

//登录窗体中的“登录”按钮代码 

private void button1_Click(object sender, EventArgs e)         

            if (txtName.Text == "123456") 

            { 

                this.DialogResult = DialogResult.OK; 

                this.Close();

             }         

}

/*********************************原创分界线****************************************/

这里有一丢丢原创内容,我一开始并没有采用博主提出的方法一、二,而是直接用语句四.System.Environment.Exit(0);
异常简单粗暴。


先介绍一下我做的程序,这个程序首先是登录界面,登陆界面有两个按钮,点击登录后,直接this.hide(),然后创新主窗体程序,但是问题在于我叉掉主窗体程序后,后台依旧有进程在运行。所以我在主窗体界面上加了一个退出系统的按钮,然后点击该按钮运行System.Environment.Exit(0);然后就不会出现进程杀不死的情况了。但是如果直接叉掉主窗体界面依旧会有进程运行。原因在于我的主线程是登录界面,叉掉主窗体界面,登录界面还是在隐藏中,没有关掉。这种方法有点投机取巧,所以最后我还是使用了方法二。


  • 5
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
您可以使用以下方法后台服务打开的 WinForm 程序设置为前台显示: 1. 在 WinForm 应用程序的 Program.cs 文件中,将启动应用程序的代码更改为以下内容: ```C# using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; namespace WinFormApp { static class Program { [STAThread] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); // 创建 WinForm 窗体 var frmMain = new MainForm(); // 如果当前进程后台进程,则将窗体设置为前台窗口 if (Environment.UserInteractive == false) { NativeMethods.AttachConsole(NativeMethods.ATTACH_PARENT_PROCESS); frmMain.Show(); } else { Application.Run(frmMain); } } } static class NativeMethods { public const int ATTACH_PARENT_PROCESS = -1; [System.Runtime.InteropServices.DllImport("kernel32.dll")] public static extern bool AttachConsole(int dwProcessId); } } ``` 2. 在 MainForm 窗体的 Load 事件中添加以下代码: ```C# private void MainForm_Load(object sender, EventArgs e) { // 如果当前进程后台进程,则将当前窗口设为前台窗口 if (Environment.UserInteractive == false) { NativeMethods.PostMessage(new HandleRef(this, this.Handle), NativeMethods.WM_SYSCOMMAND, NativeMethods.SC_RESTORE, 0); } } static class NativeMethods { public const int WM_SYSCOMMAND = 0x0112; public const int SC_RESTORE = 0xF120; [System.Runtime.InteropServices.DllImport("user32.dll")] public static extern bool PostMessage(HandleRef hWnd, int Msg, int wParam, int lParam); } ``` 这样,您就可以将后台服务打开的 WinForm 程序设置为前台显示了。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值