关闭

如果在BackgroundWorker运行过程中关闭窗体

标签: objectwindows数据库classui
658人阅读 评论(0) 收藏 举报

 

在Windows Form应用中,BackgroundWorker 类允许您在单独的专用线程上运行操作。耗时的操作(如下载和数据库事务)在长时间运行时可能会导致用户界面 (UI) 似乎处于停止响应状态。如果您需要能进行响应的用户界面,而且面临与这类操作相关的长时间延迟,则可以使用 BackgroundWorker 类方便地解决问题。由于操作是异步执行的,用户可能在异步操作执行过程中关闭当前窗体,而窗体的关闭会伴随着Dispose方法的执行。如果我们注册了BackgroundWorker的RunWorkerCompleted事件,并且在该事件处理程序中需要操作这个被Disposed的窗体,就会出现一些无法预知的异常。

一、一个简单的例子

我们写一个简单的例子来说明上述的场景:在一个非主窗体(主窗体的关闭会导致程序的终止)的Windows窗体中,一个BackgroundWorker被用于异步地执行一段耗时的操作。在我们的例子中,通过让线程休眠10秒来模拟这个“耗时操作”。方法backgroundWorker_RunWorkerCompleted是BackgroundWorker的RunWorkerCompleted事件处理方法,在这里我们通过MessageBox来显示当前窗体的IsDisposed属性值。注册到该BackgroundWorker的异步操作通过点击某个按钮开启。相关的代码如下所示。

   1: public partial class BgwForm : Form
   2: {
   3:     public BgwForm()
   4:     {
   5:         InitializeComponent();
   6:     }
   7:  
   8:     private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
   9:     {
  10:         Thread.Sleep(10000);
  11:     }
  12:  
  13:     private void btnStart_Click(object sender, EventArgs e)
  14:     {
  15:         this.backgroundWorker.RunWorkerAsync();
  16:     }
  17:  
  18:     private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
  19:     {
  20:         MessageBox.Show(string.Format("Is the form disposed? {0}", this.IsDisposed));
  21:     }
  22: }

 当该窗体被显示出来后,点击按钮让注册到该BackgroundWorker的异步操作开始执行,然后在操作结束之前(10秒)将当前窗体关闭。10秒钟之后,如右图所示的一个MessageBox会显示出来,表明在执行BackgroundWorker的RunWorkerCompleted事件处理程序的时候,承载它的窗体已经被Dispose。如果在你将一些针对窗体的操作注册到RunWorkerCompleted事件上,操作一个Disposed窗体,很难保证能否正常进行。而实际上,我们通常注册该事件在窗体上进行一些状态信息的显示,既然窗体都被关闭,这些操作就无需执行。那么,有什么方式可以确保在窗体关闭的状态下阻止RunWorkerCompleted事件处理程序的执行呢?

二、通过IsDisposed属性判断窗体的状态

我们最容易想到的肯定是在RunWorkerCompleted事件处理程序通过窗体的IsDisposed属性判断窗体的状态,并根据状态进行相应的操作。

   1: private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   2: {
   3:     if (!this.IsDisposed)
   4:     { 
   5:         //Do Something
   6:     }
   7: }

三、在Closed事件中移除对RunWorkerCompleted事件的注册

我们还有另一种方案,那就是在关闭窗体的时候将对RunWorkerCompleted事件的注册接触掉,我们只需要将该操作注册到窗体的FormClosed事件中。  

   1: private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
   2: {
   3:     //Do Something
   4: }
   5:  
   6: private void BgwForm_FormClosed(object sender, FormClosedEventArgs e)
   7: {
   8:     this.backgroundWorker.RunWorkerCompleted -= backgroundWorker_RunWorkerCompleted;
   9: }
0
0
查看评论
发表评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场

BackgroundWorker 实现多线程操作

背景介绍:            在做程序的过程中,我们很可能遇到这样的情况:当我们执行一个比较耗时的操作,即界面加载数据量略大的时,在该操作未完成之前再去操作界面,就会出现停止响应的情况,这称为界面...
  • u010028869
  • u010028869
  • 2014-11-30 00:27
  • 3240

winform+BackgroundWorker 多线程下如何停止和暂停

本文主要记录如何利用winform,BackgroundWorker线程控件和progressBar进度控件进行开发(这样启用工作线程和UI主线程,可以让进度条能进行更新,避免UI假死),同时支持启用...
  • paolei
  • paolei
  • 2017-02-07 15:13
  • 2168

C#关闭窗口方式以及线程后台运行

当你从主窗体跳转到另外一个窗体时,你的主窗体只是设置为hide,然后又你关闭非主窗体后,程序并没有退出,当你重新调试运行程序时,会出现bug,如下: 错误 12 无法将文件“obj\Debug\...
  • Feifan_Feimeng
  • Feifan_Feimeng
  • 2016-12-14 21:32
  • 762

C#之WinForm基础 运行多个窗体时,点击按钮,一次关闭所有窗体

慈心积善融学习,技术愿为有情学。善心速造多好事,前人栽树后乘凉。我今于此写经验,愿见文者得启发。 运行多个窗体时,一次关闭所有窗体。 要点在于:只需要关闭主窗体,所有窗体就全都关闭了!...
  • yushaopu
  • yushaopu
  • 2016-09-17 09:00
  • 1458

Windows 窗体启动和关闭的事件顺序

对于关注对 Windows 窗体应用程序中引发的每个事件按次序进行处理的开发人员来说,事件引发的顺序特别重要。当某种情况需要小心处理事件时(如重绘窗体的某些部分时),必须知道事件在运行时的确切引发顺序...
  • li_joy99
  • li_joy99
  • 2016-01-21 15:53
  • 1258

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

话不多说直接粘贴链接,这个博主写的非常详细 http://www.cnblogs.com/HappyEDay/p/5713707.html 这里粘贴原文权当备份了。 C#中WinForm程序退...
  • mainbyz
  • mainbyz
  • 2017-03-22 10:40
  • 3815

主窗体关闭后登录窗体仍然运行

合作的时候建立U层,从登录窗体登陆成功,然后进入主窗体,然后将登录窗体隐藏(因为登录窗体Close()了的话整个程序就会结束)。但是发现当把主窗体关闭以后,在VS里面运行的程序并没有结束,还在运行中。...
  • u013044000
  • u013044000
  • 2015-07-26 16:45
  • 921

关于VB.NET中多窗体之间的调用与关闭

关于VB.NET中多窗体之间的调用,实现多窗体之间的打开,以及打开新窗体后对旧窗体的关闭
  • FlyGodYu
  • FlyGodYu
  • 2017-11-14 22:06
  • 164

C# BackgroundWorker的使用,用于写后台多线程是个不错的

BackgroundWorker 可以用于启动后台线程。 主要的事件及参数:   1.DoWork——当执行BackgroundWorker.RunWorkerAsync方法时会触发该事件,并...
  • huquan790728805
  • huquan790728805
  • 2013-03-03 16:54
  • 3022

C#中如何去除窗体默认的关闭按钮

很多时候,在winform的设计下,会遇到新建窗体时不需要用到默认的关闭按钮的情况,而是用另外设置关闭 button或其他控件来控制窗体的关闭。   之前我遇到这个问题时,问了很多朋友,都没找到方...
  • wu_pan123
  • wu_pan123
  • 2017-05-26 08:40
  • 1273
    个人资料
    • 访问:11846242次
    • 积分:65361
    • 等级:
    • 排名:第40名
    • 原创:675篇
    • 转载:2277篇
    • 译文:0篇
    • 评论:554条
    文章分类
    文章存档
    最新评论
    计算流量