winform程序中当用多线程的时候,一般线程会更新界面控件,类似这样的代码this.Invoke。有时后台线程还没有结束,我们关闭了安全窗体,虽然窗体关闭了,但是我们的后台线程还没有还在运行。这样会报错,如下图:
1、在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke。
抛出InvalidOperationException异常。
2、无法访问已释放的对象。
抛出ObjectDisposedException异常。
我的解决办法:
我们知道如果不是在UI线程操作控件会报错, 我们要通过this.Invoke来把消息传递给UI线程,在UI线程操作。有可能我们代码中会用很多这样的this.Invoke代码 ,不可能都加上InvokeRequired这样的判断,所以我定义一个扩展方法如下:
- public static class ControlExtensions
- {
- public static void InvokeOnUiThreadIfRequired(this Control control, Action action)
- {
- try
- {
- if (!control.IsDisposed)
- {
- if (control.InvokeRequired)
- {
- control.Invoke(action);
- }
- else
- {
- action.Invoke();
- }
- }
- else
- Thread.CurrentThread.Abort();
- }
- catch (Exception ex)
- {
- }
- }
- }
上面的扩展方法加了try-catch,就不会因为关闭了窗体,更新界面控件的还未结束的问题。
这样,在线程中需要操作控件的就中需要这样调用:
- this.InvokeOnUiThreadIfRequired(() =>
- {
- lblResult.Text = string.Format("共有{0}条链接,正在检查链接状态...", urlAllCount);
- lblResult.Visible = true;
- });
这样关闭多线程的winform窗体就不会抛出ObjectDisposedException和InvalidOperationException异常了
Copyright © 广州京杭网络科技有限公司 2005-2025 版权所有 粤ICP备16019765号
广州京杭网络科技有限公司 版权所有