日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

关闭窗体后,进程仍然在运行的问题重现与解决

發(fā)布時(shí)間:2024/9/20 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 关闭窗体后,进程仍然在运行的问题重现与解决 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1?問題陳述

在開發(fā)中,遇到這樣一個(gè)問題:

點(diǎn)擊程序主窗體右上角的叉號(hào)關(guān)閉應(yīng)用程序后,程序的進(jìn)程卻沒有關(guān)閉。

通過查閱資料,了解到,產(chǎn)生此類問題的原因主要有以下兩點(diǎn):

1)程序中存在死循環(huán)。

2)程序?yàn)槎嗑€程程序,且在窗體關(guān)閉后,仍有線程在工作。

本文將針對(duì)此類問題,進(jìn)行重現(xiàn)并提出解決方案。

2?場景再現(xiàn)

@場景1

新建Windows應(yīng)用程序CloseWindowExp,程序每隔一秒鐘改變一次窗體的背景色。

程序運(yùn)行后的效果,如下圖所示(變化的過程,就請(qǐng)大家在腦子中想象一下吧)。

程序的主要代碼如下所示。

//************************************************************
//
// 窗體關(guān)閉問題示例代碼
//
// Author:三五月兒
//
// Date:2014/07/27
//
// http://blog.csdn.net/yl2isoft
//
//************************************************************
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace CloseWindowExp
{
public partial class frmCase1 : Form
{
Random rand = new Random();
public frmCase1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
while (true)
{
int c1 = rand.Next(0, 244);
int c2 = rand.Next(0, 244);
int c3 = rand.Next(0, 244);
this.BackColor = Color.FromArgb(c1,c2,c3);
Application.DoEvents();
Thread.Sleep(1000);
}
}
}
}
代碼中,通過While循環(huán)來實(shí)現(xiàn)每隔一秒鐘改變一次窗體背景色的工作,每一次循環(huán)中,會(huì)隨機(jī)生成三個(gè)整數(shù)c1、c2、c3,并使用這三個(gè)整數(shù)來生成窗體的背景色,緊接著,執(zhí)行Application.DoEvents()方法,使用此方法可以確保即使在循環(huán)中窗體也有反映(要不,你去掉再看看會(huì)有什么效果),每次循環(huán)的最后會(huì)讓程序Sleep一小會(huì)(1s鐘),這樣就可以使顏色變化的間隔近似保持在1s鐘左右。
運(yùn)行程序再點(diǎn)擊窗體右上角的叉號(hào)關(guān)閉窗體(是關(guān)閉窗體哦,其實(shí)以前我一直都認(rèn)為,關(guān)閉了窗體也就關(guān)閉了程序,現(xiàn)在看來,這是不正確的),再打開任務(wù)管理器,打開“進(jìn)程”項(xiàng),在列表中尋找CloseWindowExp的身影,很不幸,找到了,請(qǐng)看下圖。

@場景二

場景二所給示例,完成場景一示例一樣的工作,只是將工作轉(zhuǎn)移至一個(gè)新的工作線程中。

下面是場景二示例的主要代碼。

//************************************************************
//
// 窗體關(guān)閉問題示例代碼
//
// Author:三五月兒
//
// Date:2014/07/27
//
// http://blog.csdn.net/yl2isoft
//
//************************************************************
using System;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
namespace CloseWindowExp1
{
public partial class frmCase2 : Form
{
Random rand = new Random();
public frmCase2()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
Thread t = new Thread(()=>
{
if (this.InvokeRequired)
{
this.Invoke(new Action(() =>
{
while (true)
{
int c1 = rand.Next(0, 244);
int c2 = rand.Next(0, 244);
int c3 = rand.Next(0, 244);
this.BackColor = Color.FromArgb(c1, c2, c3);
Application.DoEvents();
Thread.Sleep(1000);
}
}));
}
});
t.Start();
}
}
}
其實(shí),對(duì)于這里場景二所給的的示例,我是有一點(diǎn)不放心的,生怕使用它不能很好地說明我想要表達(dá)的內(nèi)容,因?yàn)楸举|(zhì)上他跟示例一沒有任何差別,都是因?yàn)樵诔绦蛑写嬖谝粋€(gè)死循環(huán)才導(dǎo)致了問題的發(fā)生。

在研究這類問題發(fā)生的原因時(shí),我們完全可以這樣去考慮,當(dāng)窗體被關(guān)閉后,程序?yàn)槭裁催€在運(yùn)行呢,肯定是因?yàn)槌绦蜻€有沒干完的工作,當(dāng)然這件工作有可能再過一會(huì)就干完了,也有可能永遠(yuǎn)也干不完(死循環(huán)),至于這工作是誰干的,是主線程,還是工作線程,本質(zhì)上沒有區(qū)別。通過我們所給的兩個(gè)實(shí)例,正好說明這點(diǎn),因?yàn)閷?shí)例一的工作是在主線程中完成的,而實(shí)例二的工作是在工作線程中完成的。但是,不管是主線程,還是工作線程,只要存在未完成的工作都會(huì)導(dǎo)致此類問題的發(fā)生。所以,此類問題的原因,最終可以歸結(jié)為一點(diǎn):關(guān)閉窗體時(shí),只要有線程還在工作,進(jìn)程都不會(huì)被結(jié)束。

在實(shí)際開發(fā)中,我們經(jīng)常會(huì)使用一個(gè)工作線程去干一些重復(fù)的工作,所以,在多線程開發(fā)中,更容易出現(xiàn)死循環(huán)或者關(guān)閉了窗體還需要工作一段時(shí)間的場景。因此,多線程開發(fā)中更要注意此類問題的發(fā)生。

找到了原因,解決問題就簡單了。對(duì)于此類問題的解決,只要確保在窗體關(guān)閉后沒有任何線程在工作即可。至于具體解決方案可以視情況而定。

3 解決方法

@方法1

將循環(huán)條件while?(true)修改為while?(this.Visible)。

這樣一來,當(dāng)窗體關(guān)閉后,窗體的Visible屬性值變?yōu)閒alse,則while循環(huán)隨即被終止,進(jìn)而進(jìn)程也會(huì)被正常結(jié)束。

@方法2

在窗體的FormClosing事件處理方法中,使用代碼System.Environment.Exit(0)強(qiáng)制退出當(dāng)前進(jìn)程,這樣一來,不管進(jìn)程下是否還有線程在工作,都會(huì)一概結(jié)束。

private void frmCase2_FormClosing(object sender, FormClosingEventArgs e)
{
System.Environment.Exit(0);
}
方法1的原理是結(jié)束程序中的死循環(huán)進(jìn)而結(jié)束線程,從而使進(jìn)程能夠正常結(jié)束;而方法2是不管線程有沒有工作都強(qiáng)制關(guān)閉所有線程進(jìn)而正常結(jié)束進(jìn)程。
我們這里不去探討哪種方法更好,只想對(duì)解決此類問題的思考方向給出一個(gè)說明,那就是:通過結(jié)束所有線程的工作來保證進(jìn)程的正常結(jié)束。當(dāng)然這也是本文的一個(gè)主題。

好了,就寫到這里了,希望沒有離題。
---------------------

總結(jié)

以上是生活随笔為你收集整理的关闭窗体后,进程仍然在运行的问题重现与解决的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。