如果在BackgroundWorker运行过程中关闭窗体…
2010-11-25 13:34
1231 查看
在Windows Form应用中,BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。由于操作是异步执行的,用户可能在异步操作执行过程中关闭当前窗体,而窗体的关闭会伴随着Dispose方法的执行。如果我们注册了BackgroundWorker的RunWorkerCompleted事件,并且在该事件处理程序中需要操作这个被Disposed的窗体,就会出现一些无法预知的异常。
[/code]
![](https://oscdn.geek-share.com/Uploads/Images/Content/201505/e2d75c06715c8d79505c676552ee984e.png)
当该窗体被显示出来后,点击按钮让注册到该BackgroundWorker的异步操作开始执行,然后在操作结束之前(10秒)将当前窗体关闭。10秒钟之后,如右图所示的一个MessageBox会显示出来,表明在执行BackgroundWorker的RunWorkerCompleted事件处理程序的时候,承载它的窗体已经被Dispose。如果在你将一些针对窗体的操作注册到RunWorkerCompleted事件上,操作一个Disposed窗体,很难保证能否正常进行。而实际上,我们通常注册该事件在窗体上进行一些状态信息的显示,既然窗体都被关闭,这些操作就无需执行。那么,有什么方式可以确保在窗体关闭的状态下阻止RunWorkerCompleted事件处理程序的执行呢?
[/code]
[/code]
一、一个简单的例子
我们写一个简单的例子来说明上述的场景:在一个非主窗体(主窗体的关闭会导致程序的终止)的Windows窗体中,一个BackgroundWorker被用于异步地执行一段耗时的操作。在我们的例子中,通过让线程休眠10秒来模拟这个“耗时操作”。方法backgroundWorker_RunWorkerCompleted是BackgroundWorker的RunWorkerCompleted事件处理方法,在这里我们通过MessageBox来显示当前窗体的IsDisposed属性值。注册到该BackgroundWorker的异步操作通过点击某个按钮开启。相关的代码如下所示。[code] public partial class BgwForm : Form { public BgwForm() { InitializeComponent(); } private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e) { Thread.Sleep(10000); } private void btnStart_Click(object sender, EventArgs e) { this.backgroundWorker.RunWorkerAsync(); } private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { MessageBox.Show(string.Format("Is the form disposed? {0}", this.IsDisposed)); } }
[/code]
![](https://oscdn.geek-share.com/Uploads/Images/Content/201505/e2d75c06715c8d79505c676552ee984e.png)
当该窗体被显示出来后,点击按钮让注册到该BackgroundWorker的异步操作开始执行,然后在操作结束之前(10秒)将当前窗体关闭。10秒钟之后,如右图所示的一个MessageBox会显示出来,表明在执行BackgroundWorker的RunWorkerCompleted事件处理程序的时候,承载它的窗体已经被Dispose。如果在你将一些针对窗体的操作注册到RunWorkerCompleted事件上,操作一个Disposed窗体,很难保证能否正常进行。而实际上,我们通常注册该事件在窗体上进行一些状态信息的显示,既然窗体都被关闭,这些操作就无需执行。那么,有什么方式可以确保在窗体关闭的状态下阻止RunWorkerCompleted事件处理程序的执行呢?
二、通过IsDisposed属性判断窗体的状态
我们最容易想到的肯定是在RunWorkerCompleted事件处理程序通过窗体的IsDisposed属性判断窗体的状态,并根据状态进行相应的操作。[code] private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { if (!this.IsDisposed) { //Do Something } }
[/code]
三、在Closed事件中移除对RunWorkerCompleted事件的注册
我们还有另一种方案,那就是在关闭窗体的时候将对RunWorkerCompleted事件的注册接触掉,我们只需要将该操作注册到窗体的FormClosed事件中。[code] private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { //Do Something } private void BgwForm_FormClosed(object sender, FormClosedEventArgs e) { this.backgroundWorker.RunWorkerCompleted -= backgroundWorker_RunWorkerCompleted; }
[/code]
相关文章推荐
- 如果在BackgroundWorker运行过程中关闭窗体
- 如果在BackgroundWorker运行过程中关闭窗体…
- 如果在BackgroundWorker运行过程中关闭窗体…
- SharePoint 2013 APP 之---很抱歉,应用程序已关闭。如果您知道运行服务器的人员,请告诉他们启用应用程序。
- winForm窗体关闭按钮实现托盘后台运行(类似QQ托盘区运行)
- 主窗体关闭后登录窗体仍然运行
- C#之WinForm基础 运行多个窗体时,点击按钮,一次关闭所有窗体
- java窗体运行时最大化及关闭方法示例
- Spark --- 启动、运行、关闭过程
- C# 关闭登录窗体,进入主窗体后,主窗体关闭,程序进程仍在运行的问题
- 通过文件锁实现,程序开始运行时,先判断文件是否存在,若存在则表明该程序已经在运行了,如果不存在就用open函数创建该文件,程序退出时关闭文件并删除文件。
- 关闭模式窗体后,如果该窗体是由父窗体show出来的...
- winForm窗体关闭按钮实现托盘后台运行(类似QQ托盘区运行)
- 关闭窗体消息过程
- Spark --- 启动、运行、关闭过程
- winForm窗体关闭按钮实现托盘后台运行(类似QQ托盘区运行)
- C# 关闭登录窗体,进入主窗体后,主窗体关闭,程序进程仍在运行的问题
- java窗体运行时最大化及关闭方法示例
- 在服务器运行过程中的nginx重启、启动、关闭
- Spark --- 启动、运行、关闭过程