前几天做ArcEngine二次开发时需要连接ArcSDE数据库,感觉连接ArcSDE的时间有点长,想着在连接ArcSDE之前跳出一个带等待动画的界面等待ArcSDE的链接,于是写了如下代码:


private void buttonX1_Click(object sender, EventArgs e)//button1在主窗口中
{Waitting waitting = new Waitting();waitting.show();//form2加载时有等待动画 ConnectSDE();//运行时间5秒左右 waitting.hide();//等待界面消失,回到主界面}

后来在运行的时候发现waitting中的动画根本无法运行,后来百度了才知道是线程阻塞问题。当一个WinForm程序在事件函数中进行IO操作、网络操作或耗CPU大的操作时,窗体会出现明显的卡顿现象。原因在于窗体的消息循环被耗时的操作停住了,UI线程被阻塞。在相关操作没有完成之前,用户不能对窗体进行任何的操作,包括关闭应用程序,此时用户看到的该窗体会出现无法响应,而我form2的动画效果就这样被阻塞了。


此时我们自己解决问题的思路肯定是——能不能将阻塞线程的操作在另外一个线程中执行,这样就不会堵塞UI线程。

然而从另外一个线程操作windows窗体上的控件,就会和主线程产生竞争,造成不可预料的结果。因此windowsGUI编程有一个规则,就是只能通过创建控件的线程来操作控件的数据。

好在因此Control类实现了ISynchronizeInvoke接口,提供了Invoke和BeginInvoke方法来提供让其它线程更新GUI界面控件的机制。

两者区别是:Invoke,需要等待委托的方法执行返回后才执行下面的代码;begininvoke则不需要。

所以最后的解决方案如下:

private void buttonX1_Click(object sender, EventArgs e)  {Waitting waitting = new Waitting();  waitting.Show();  Task.Factory.StartNew(() => // 将阻塞线程的操作在另外一个线程中执行,这样就不会堵塞UI线程。   {   ConnectSDE(); //运行时间5s左右MessageBox.Show("连接SDE数据库成功", "信息", MessageBoxButtons.OK, MessageBoxIcon.Information);  waitting.BeginInvoke((Action)waitting.Close);//BeginInvoke方法返回UI线程更新UI界面控件的机制。   });  }

这样程序在ConnectSDE( )方法运行的过程中不会阻塞主线程,Waitting界面的动画也可以展示了:

ConnectSDE( )方法运行结束,弹窗提示。确定后BeginInvoke方法返回UI线程关闭等待窗口:

总结就是:对于UI阻塞,可以将阻塞线程的操作放在另外一个线程执行;而对于跨线程调用,可以使用invoke()或者BeginInvoke() 来解决问题。

一直没提异步操作的原因是我个人不太理解线程操作与异步操作的区别。我个人的理解是:异步与同步是相对的,同步即阻塞,即做A的时候做不了B;AB可以同时做互不干扰就叫异步。而为了实现异步,可以利用多线程。异步是目的,多线程是手段。BeginInvoke、EndInvoke这些异步操作应该是.NET精心封装好的,未必与多线程有关。这样就可以理解百度百科异步词条百度词条—异步。异步不需要占用额外线程这句话了。

同样的,我个人感觉异步是相对的。在上面的解决方案中,如果使用了Invoke同步方法(实际上这里用Invoke也没啥区别),会在Task中阻塞线程,然而Invoke会回调UI线程的委托,即线程中同步,线程间异步,听上去是不是很玄乎。。。

--------------------- 
作者:DanteLzp 
来源:CSDN 
原文:https://blog.csdn.net/DanteLzp/article/details/69499560

解决C#界面假死问题相关推荐

  1. 解决Qt 5程序运行时界面假死的方法

    在Qt 5的GUI程序中,主线程也叫GUI线程,因为它是唯一被允许执行GUI相关操作的线程.对于一些计算量比较大的非常耗时的操作,如果放在主线程中,就是出现界面无法响应的问题.这种问题的解决一种方式是 ...

  2. qt开启线程界面假死问题解决

    一.前言 在 使用qt高速读取传感器数据时,如果想要将数据实时刷新在界面,就需要开启一个线程单独去跑读取数据函数,并反馈给主程序,否则在主程序中读取和刷新界面会很卡很卡,但是在开启多线程,无外接鼠标键 ...

  3. WinForm程序界面假死,寻求完美解决方案

    WinForm程序界面假死,寻求完美解决方案 参考文章: (1)WinForm程序界面假死,寻求完美解决方案 (2)https://www.cnblogs.com/funying/p/3230873. ...

  4. 解决WindowsForm窗体假死的状态

    转载 http://blog.sina.com.cn/s/blog_621e24e201015r29.html 另一篇非常不错的博文:http://www.cnblogs.com/wangshenhe ...

  5. C# Application.DoEvents() 处理队列消息,防界面假死。

    该方法可以处理当前队列的消息,比如一个for循环 5000次 向TextBox中追加文本,那肯定会假死一会儿的. 此时便可使用Application.DoEvents()来处理队列的信息. 简单说下使 ...

  6. C# 防止界面假死 多线程进度条的合理使用

    好长时间没发博了 .. 这两天用C#写了一个批量分割图片前景的软件,最初的时候没用多线程,执行批量分割就假死,后来就换成了多线程,结果还是假死.. 网上找了几篇博文看了看,才发现错误的地方. 好了,首 ...

  7. MFC多线程处理界面假死之红外图像数据获取和excel写入

    在MFC主界面某个Button Click事件中起一个线程去做处理一些事情,在起的线程运行完毕后,接着跑Click起线程后的代码,已达到按顺序执行,保证时许正确的目的. 问题 通常处理一个线程等待用 ...

  8. WinForm多线程+委托防止界面假死

    当有大量数据需要计算.显示在界面或者调用sleep函数时,容易导致界面卡死,可以采用多线程加委托的方法解决 using System; using System.Collections.Generic ...

  9. C#多线程与UI响应 防止界面假死不响应(子线程创建的窗体获取消息响应用Application.DoEvent )

    一. 概述 在使用C#进行应用程序设计时,经常会采用多线程的方式进行一些后台任务的工作.对于不同的应用场景,使用的策略也不尽相同. 1. 后台循环任务,少量UI更新:例如批量上传文件,并提供进度.这种 ...

最新文章

  1. REST服务的自动化测试
  2. python 动漫卡通人物图片大全_用Python把人物头像动漫化,不同的表情给你不同的惊喜...
  3. 算法工程师怎样提升业务理解能力?
  4. Win XP环境Tuxedo8.1安装、配置指南
  5. 轧机用弹性阻尼体反力计算_「轴承知识」轧机轴承故障频繁怎么办?必要的检查维护不可少...
  6. python驱动级模拟按键大师_AB叔_C#驱动级模拟按键操作
  7. 计算机控制手机源码,Total Control电脑控制手机助手
  8. python案例实操_Python 操作 Word 案例
  9. Docker 学习前置,网络IP地址以及交互
  10. 关于chrome浏览器不能正常访问百度的解决方法
  11. 手机影像内卷几时休?
  12. 用表格做出的阴影扇形图
  13. 技术与市场杂志技术市场杂志社技术与市场编辑部2022年第9期目录
  14. UNI-APP在自定义组件中内嵌H5/Html网页,可自定义webview大小,加载不闪屏
  15. 5th-Generation Mobile Communication Technology(一)
  16. 驱动开发:内核读取SSDT表基址
  17. linux rz上传工具的安装使用
  18. Outlook2016创建账户后无法发送和接收邮件的解决办法
  19. Linux C 进程间的信号通信
  20. 大学c语言实验报告,上海工程技术大学C语言实验报告.doc

热门文章

  1. 微信公众号 语音转文字api_原来微信不仅能实现语音转文字,还能实现文字转语音!你还不知吗...
  2. 轻松解决 f2pool鱼池ethermine连接失败antpool矿池连接不上的问题E池连接超时
  3. 1-106兔子繁衍问题
  4. 叮!丰巢智能柜那些贴心服务的正确打开方式
  5. 使用openSSL制作SSL证书
  6. 上海气象局 mysql_根据中国气象局提供的API接口实现天气查询
  7. android图片分辨率改变,Android实现改变一个图片的像素值
  8. 腾讯云学生服务器如何购买
  9. 浮点数和整数的区别python_浮的部首|浮的拼音|浮的组词|浮的意思 - 查字典
  10. 【HTMLCSS】运维、后端你该会的前端基本内容