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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

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

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

1?問題陳述

在開發中,遇到這樣一個問題:

點擊程序主窗體右上角的叉號關閉應用程序后,程序的進程卻沒有關閉。

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

1)程序中存在死循環。

2)程序為多線程程序,且在窗體關閉后,仍有線程在工作。

本文將針對此類問題,進行重現并提出解決方案。

2?場景再現

@場景1

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

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

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

//************************************************************
//
// 窗體關閉問題示例代碼
//
// 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循環來實現每隔一秒鐘改變一次窗體背景色的工作,每一次循環中,會隨機生成三個整數c1、c2、c3,并使用這三個整數來生成窗體的背景色,緊接著,執行Application.DoEvents()方法,使用此方法可以確保即使在循環中窗體也有反映(要不,你去掉再看看會有什么效果),每次循環的最后會讓程序Sleep一小會(1s鐘),這樣就可以使顏色變化的間隔近似保持在1s鐘左右。
運行程序再點擊窗體右上角的叉號關閉窗體(是關閉窗體哦,其實以前我一直都認為,關閉了窗體也就關閉了程序,現在看來,這是不正確的),再打開任務管理器,打開“進程”項,在列表中尋找CloseWindowExp的身影,很不幸,找到了,請看下圖。

@場景二

場景二所給示例,完成場景一示例一樣的工作,只是將工作轉移至一個新的工作線程中。

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

//************************************************************
//
// 窗體關閉問題示例代碼
//
// 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();
}
}
}
其實,對于這里場景二所給的的示例,我是有一點不放心的,生怕使用它不能很好地說明我想要表達的內容,因為本質上他跟示例一沒有任何差別,都是因為在程序中存在一個死循環才導致了問題的發生。

在研究這類問題發生的原因時,我們完全可以這樣去考慮,當窗體被關閉后,程序為什么還在運行呢,肯定是因為程序還有沒干完的工作,當然這件工作有可能再過一會就干完了,也有可能永遠也干不完(死循環),至于這工作是誰干的,是主線程,還是工作線程,本質上沒有區別。通過我們所給的兩個實例,正好說明這點,因為實例一的工作是在主線程中完成的,而實例二的工作是在工作線程中完成的。但是,不管是主線程,還是工作線程,只要存在未完成的工作都會導致此類問題的發生。所以,此類問題的原因,最終可以歸結為一點:關閉窗體時,只要有線程還在工作,進程都不會被結束。

在實際開發中,我們經常會使用一個工作線程去干一些重復的工作,所以,在多線程開發中,更容易出現死循環或者關閉了窗體還需要工作一段時間的場景。因此,多線程開發中更要注意此類問題的發生。

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

3 解決方法

@方法1

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

這樣一來,當窗體關閉后,窗體的Visible屬性值變為false,則while循環隨即被終止,進而進程也會被正常結束。

@方法2

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

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

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

總結

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

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。