C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法

这篇具有很好参考价值的文章主要介绍了C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


前言

如果要解决“C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行”的问题,可以直接点击目录跳转到3.4关闭窗体的多种方法。

前面为记录遇到该问题的一些过程。
之前用C#做了一个日志备份的窗体应用程序,最近把这个程序完善了一下,在窗体上显示了配置文件中的一些信息,并且增加了更新按钮,点击会将一些比较重要的配置写到日志文件中。
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法

但是在测试的时候发现了一个问题,运行生成的Release文件中的exe文件(因为最后要放到服务器上使用,不会将整个项目拷贝过去,只拷贝Release文件)。
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法

在第一次运行的时候没什么问题,但是将程序关闭后,修改完配置文件中的线程数再启动的时候,窗体可以正常显示,备份功能也可以正常实现,但是日志中没有写入任何东西,点击更新按钮也没有将配置文件中的信息写入日志当中。下面的是第一次运行的时候写入的,但是后面就不显示了,点击更新按钮也不显示。
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法


一、可能的原因1

1.1猜想1

因为程序里面有使用多线程,我想会不会是在vs上运行程序生成项目的时候,线程数被固定了,后续更改配置文件的线程数与生成时项目中的线程数不一致导致程序出错。
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法

1.2验证

首先生成了一个4线程的项目,然后运行Release文件中的exe文件,发现功能没问题,日志也可以写入。
然后将窗体关闭,将配置文件中的线程数改为3,窗体启动后发现无法正常使用。
然后将窗体关闭,将配置文件中的线程数改为2,亦是如此。
然后将窗体关闭,将配置文件中的线程数改回4,亦是如此。

后续又做了如下验证:
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法
期间有debug,开启线程没有问题,会按照配置文件中修改的参数来开启对应的线程,点击按钮也有执行日志写入功能,只是.log日志文件中没有实际写入,这说明程序应该是没有问题的。

1.3结论

根据上面的验证结果,得出的结论是跟生成的线程数没有关系。

二、可能的原因2

2.1猜想2

我想起之前在更新版本的时候,需要删除之前的版本或者给之前版本的文件加上日期,在应用窗体已经关闭的情况下还是显示该文件被占用无法删除或者修改,打开任务管理器,会发现有好几个该程序的进程正在运行,如实想会不会是因为该程序在上次关闭的时候没有彻底关闭,后来又运行exe的时候导致开了好几个,导致日志无法写入。

2.2验证

运行Release文件中的exe文件,将窗体应用关闭后,发现后台进行并没有关闭
C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法
此时不做任何修改,再执行exe文件,窗体启动后发现无法正常使用。
然后手动在任务管理器中结束该进程,重新启动exe,发现功能可以正常使用。

修改配置文件中的线程数,重新启动exe,发现功能可以正常使用。

2.3结论

功能无法正常使用就是因为程序进行没有完全结束,即使关闭了窗体应用,但是程序还在后台运行,如果在每次启动前去任务管理器将该进程关闭,该就可以解决。

但是该方法比较麻烦,而且治标不治本,于是便开始查询为什么会出现这种情况。

三、最终解决办法

3.1出现的原因:

有的说是有许多人在用做c# 做登录窗体时,登录成功后当前登录Form关闭,打开Main窗体,但Main窗体点关闭按钮后程序仍在进程仍旧在运行。
事实上,关闭Main窗体,只是关闭了Main窗体的线程,并没有关闭程序的主线程,即程序的主线程为登录From。

但是我这个只有一个窗口,所以不存在多窗体没有关闭的情况。
我的真实情况是程序里面开线程了,有托管线程(非主线程),无法干净地退出。

3.2解决办法1

有的说在FormClosing中添加Application.Exit()可以彻底结束进程。
怎么使用FormClosing事件,可以参考:
链接: FormClosing事件在哪,怎么打开FormClosing事件

于是添加了如下代码:

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("将要关闭窗口,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                e.Cancel = false;
                Application.Exit();
            }
            else
            {
                e.Cancel = true;
            }
        }

但是发现关闭窗体后程序依旧没有彻底关闭。

当我们关闭窗口时,只是停止了当前窗口的消息循环。当Main函数中有消息循环的窗口,这个消息循环结束后,Main函数就基本上完成了历史使命,整个应用程序自然就结束了。

而Application.Exit()方法是终止所有线程上的消息循环,一般情况下,无论在什么地方调用此方法,程序就能退出。

但是如果你在程序中加入了某些耗时甚至是死循环的线程,那么即使是消息循环终止,程序也依然不会结束。

而且这个代码还有一个问题,会导致显示确定退出的两次对话框,第一次单击“确定”第二次单击任何一个都会退出。

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

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("将要关闭窗口,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                e.Cancel = false;
            }
            else
            {
                e.Cancel = true;
            }
        }
             //20221227 窗体关闭
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
        }

这样就不会出现弹出两次窗口的情况,但是程序没有彻底结束的问题依旧没有解决。

3.3解决办法2

在Form1_FormClosed事件中加入强制结束进程并退出。

private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("将要关闭窗口,是否继续?", "询问", MessageBoxButtons.YesNo) == DialogResult.Yes)
            {
                e.Cancel = false;
            }
            else
            {
                e.Cancel = true;
            }
        }
             //20221227 窗体关闭
        private void Form1_FormClosed(object sender, FormClosedEventArgs e)
        {
            Application.Exit();
            //强制结束进程并退出
			//System.Diagnostics.Process.GetCurrentProcess().Kill();
			System.Environment.Exit(0);
        }

3.4关闭窗体的多种方法

在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); 这是最彻底的退出方式,不管什么线程都被强制退出,把程序结束的很干净。

3.5FormClosing事件和FormClosed事件

这里来说一下FormClosing事件和FormClosed事件

FormClosing事件
在窗体关闭时,FormClosing事件发生。此事件会得到处理。从而释放与窗体相关的所有资源。
如果取消此事件,则窗体仍然保持打开状态。
当窗体显示为模式对话框时,单击“关闭”会隐藏窗体并将DialogResult属性设为Cancel。
通过在些事件中设置DialogResult属性可以在用户单击右上角关闭按钮时重写DialogResult的值。

FormClosed事件
在用户或Application类的Close方法或Exit方法关闭窗体后,会发生FormClosed事件。
可以使用此事件释放窗体的一些资源。还可以使用此事件保存输入窗体中的一些信息或者更新父窗体。文章来源地址https://www.toymoban.com/news/detail-425964.html


到了这里,关于C#winform 点叉叉按钮关闭一form窗体应用后,后台进程仍在运行的解决办法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C# winform窗体UI美化后实现最大化、最小化、还原、关闭、窗体移动等等-2023/1/11

    在做winform窗体UI美化时,一般都需要将窗体的FormBorderStyle属性设为None,之后窗体就会没有最上面的标题栏,然后按照UI进行界面的设计。美化的代价就是窗体本来标题栏的相关操作,例如双击自动最大化,再次双击又恢复正常大小,以及上窗体关闭、最小化等功能就都需要自

    2024年02月08日
    浏览(43)
  • winform学习(3)-----Windows窗体应用和Windows窗体应用(.Net Framework)有啥区别?

    在学习winform的时候总是会对这两个应用不知道选择哪个?而且在学习的时候也没有具体的说明 首先说一下我是在添加控件的时候出现了以下问题 对于使用了 Windows窗体应用 这个模板的文件在工具箱中死活不见控件。 在转换使用了 Windows窗体应用(.NET Framework) 模板之后就出现

    2024年02月14日
    浏览(25)
  • C#实例:多功能Windows窗体应用程序Helloworld_WinForm

    有了创建一个Windows窗体应用程序的经验,就可以开始尝试运用更多的控件实现更多丰富的功能界面。以下分享我基于项目Helloworld_WinForm 使用常用C#Windows窗体控件 实现一些小功能。 每一节标题为所用到的控件,全文以实际制作过程为序编制。 1、创建窗体Form 项目创建时会默

    2024年02月04日
    浏览(43)
  • C#:如何用VS开启人生中第一个Windows窗体应用程序(Winform)?

    摘要:Windows窗体应用程序(Winform,下文以此指代)既能有效、直观地设计Windows窗体界面,又支持内部逻辑的编写。那么,对于C#初学者来说,如何开启第一个Winform程序呢?    编程语言:C# 编程环境:Visual Studio 2019 目录 步骤 每篇寄语         1、点击桌面Visual Studio 2019图

    2024年02月09日
    浏览(43)
  • 【WinForm】WinForm常见窗体技术汇总

    窗体调用外部程序与渐变窗体 按回车键跳转窗体中的光标焦点 剪切板操作 实现拖放操作 移动的窗体 抓不到的窗体 MDI窗体 提示关闭窗体 窗体正在变色: 窗体调用网络页面–启动浏览器: 窗体调用本地程序–启动记事本: 按下enter键,光标会向下移动: 第一个text中输入内

    2024年02月08日
    浏览(34)
  • winform窗体

    WinForm,是·Net开发平台中对Windows Form的一种称谓。WinForm是窗体应用程序,由若干个窗体应用组成,基于C/S架构 (1)基本控件: label 文本提示 TextBox 文本框 button      按钮 radiobutton 单选按钮 panel       面板(相当于小容器) check 复选框 combox        下拉列表框 listbox  列表

    2024年02月08日
    浏览(57)
  • Winform窗体使用IOC容器

    Winform窗体如何使用IOC容器呢?在nuget中添加Microsoft.Extensions.DependencyInjection 接着在Program类Main方法中添加一下代码 在此类中继续补充以下代码 以后你的注入只需要在 static void ConfigureServices(IServiceCollection services)这个方法中注入就行了 全景图:   我把窗体也注入了,不过不是

    2024年02月12日
    浏览(33)
  • 【C#】【WinForm】MDI窗体

    MDI窗体的相关学习使用 1、设置MDI父窗体  在属性中找到IsMdiContainer选项,设置为True 2、添加MDI子窗体,在项目中依次选择添加-窗体,然后一直默认即可  添加后的项目目录(Form1为父窗口,Form2、Form3为子窗口)  3、在Form1.cs中,创建对应MDI子窗口的对象并调用显示出来 保存

    2024年02月08日
    浏览(35)
  • winform窗体闪烁问题解决方式

    winform窗体闪烁问题解决方式 1、使用窗体双缓冲 SetStyle(ControlStyles.UserPaint | ControlStyles.AllPaintingInWmPaint | ControlStyles.OptimizedDoubleBuffer, true); UpdateStyles(); 窗体的DoubleBuffered 指示是否对控件进行双缓存处理。 2、使用CreateParams的使用解决闪屏问题

    2024年02月12日
    浏览(77)
  • C#开发Windouw窗体之Form窗体及示例(基础)

    Forms窗体也称为窗口,通过窗体可以显示信息、请求用户输入以及通过网络与远程计算机通信。 我们首先要明白三点: 1.窗体也是对象,窗体类定义了生成窗体的模板,每当实例化一个窗体类,就产生一个窗体 2.Form类是所有窗体类的基类。 3.在一个项目中,每个窗体都有自己

    2024年02月02日
    浏览(27)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包