多线程编程中遇到的问题总结
2013-12-17 21:51
190 查看
1.1 多线程就是多个线程吗?比如说,一个程序里面,原本启动一个线程,现在改启动多个线程,这就叫做多线程了?
通过收集资料,了解到程序是依赖进程的,一个程序中至少包括一个进程,进程是一个程序的容器;线程在进程里面存在,一个进程可以包括至少一个以上的线程,线程只是一段执行的代码片段。多线程的执行,只是cpu切换时间片分别执行各线程的概念,线程多了,cpu来回切换执行线程时不见得效率会提高。一个进程里面包含多个线程,就叫做多线程。
1.2 线程中访问WinForm控件时,“对 Windows 窗体控件进行线程安全调用”之类提示错误:
子线程访问 Windows 窗体控件,编译器认为这不是安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。所以,线程中访问Windows窗体时需要注意。
Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个Invoke
方法来将调用封送到适当的线程。Invoke 生成同步方法调用;BeginInvoke 生成异步方法调用。提供代码如下:
代码说明:
既然写线程去做一些复杂耗时的工作,那么没有必要将for循环的内容先写入list,再通过this.listbox1.DataSource=list;赋值,这样的赋值只会让程序卡顿没有反应。因为DataSource还是一次性的填装容器。
1.3 时间间隔很长(>=1M) 线程怎么处理:
思考之后,我觉得,如果是一段程序需要1个月才执行一次,这样的代码不适合写到线程中去,想想看难道要让Thread.sleep(1M)或Timer间隔1M?这是不现实的,因为程序随时可能退出或中断啊。所以说,如果超过一个月执行一次的程序,可以采用windows计划任务或者windows service或者Sql的计划任务什么的等。Sql计划任务什么的以后研究研究,这个我现在也不懂。
所以,线程更适合短期的复杂操作。当然,在实际项目中,有一个轮询的程序,每个月清理一下客户端日志并进行一次同步操作,我还是采用的线程处理的。因为,在项目中有很多的情况,有的业务数据操作频繁,大约5分钟就要一次同步,这样我在每次同步的时候都进行一次判断,同步前先判断一下在配置文件中的该情况的上次同步时间与本次轮询的时间差是不是超过了1M,如果超过了1M,本次就需要同步,反之pass。这样,不管中间有多少次停机或者网络中断都不影响我的同步了。当然这只是一种特殊情况。
通过收集资料,了解到程序是依赖进程的,一个程序中至少包括一个进程,进程是一个程序的容器;线程在进程里面存在,一个进程可以包括至少一个以上的线程,线程只是一段执行的代码片段。多线程的执行,只是cpu切换时间片分别执行各线程的概念,线程多了,cpu来回切换执行线程时不见得效率会提高。一个进程里面包含多个线程,就叫做多线程。
1.2 线程中访问WinForm控件时,“对 Windows 窗体控件进行线程安全调用”之类提示错误:
子线程访问 Windows 窗体控件,编译器认为这不是安全的。如果有两个或多个线程操作某一控件的状态,则可能会迫使该控件进入一种不一致的状态。所以,线程中访问Windows窗体时需要注意。
Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个Invoke
方法来将调用封送到适当的线程。Invoke 生成同步方法调用;BeginInvoke 生成异步方法调用。提供代码如下:
private void SetFillListBox(string strItem) { this.listBox1.Items.Add(strItem); } void FillListBoxWithInvoke() { for (int i = 0; i < 1000000; i++) { if (listBox1.InvokeRequired)//此处表示需要唤醒UI线程 { try { SetFillTextCallback d = new SetFillTextCallback(SetFillListBox); this.Invoke(d, ("Item" + i)); } catch (ObjectDisposedException) {//do nothing.... } } else { SetFillListBox("Item"+i); } } }
代码说明:
既然写线程去做一些复杂耗时的工作,那么没有必要将for循环的内容先写入list,再通过this.listbox1.DataSource=list;赋值,这样的赋值只会让程序卡顿没有反应。因为DataSource还是一次性的填装容器。
1.3 时间间隔很长(>=1M) 线程怎么处理:
思考之后,我觉得,如果是一段程序需要1个月才执行一次,这样的代码不适合写到线程中去,想想看难道要让Thread.sleep(1M)或Timer间隔1M?这是不现实的,因为程序随时可能退出或中断啊。所以说,如果超过一个月执行一次的程序,可以采用windows计划任务或者windows service或者Sql的计划任务什么的等。Sql计划任务什么的以后研究研究,这个我现在也不懂。
所以,线程更适合短期的复杂操作。当然,在实际项目中,有一个轮询的程序,每个月清理一下客户端日志并进行一次同步操作,我还是采用的线程处理的。因为,在项目中有很多的情况,有的业务数据操作频繁,大约5分钟就要一次同步,这样我在每次同步的时候都进行一次判断,同步前先判断一下在配置文件中的该情况的上次同步时间与本次轮询的时间差是不是超过了1M,如果超过了1M,本次就需要同步,反之pass。这样,不管中间有多少次停机或者网络中断都不影响我的同步了。当然这只是一种特殊情况。
相关文章推荐
- Cloudera Manager5安装总结遇到问题及解决办法
- 近期改BUG遇到的小问题及经验总结
- Android 开发中的遇到的一些细节问题总结
- FLEX tree动态获得信息时遇到的问题总结
- iOS下的智能硬件开发遇到的问题总结
- elasticjob遇到问题总结
- KSTORE日常工作遇到问题总结
- 一个简单的安卓小应用,开发步骤以及遇到的各种问题总结
- 关于Think3 配置邮箱发送遇到的问题总结
- Hi3516A开发--编译整个osdrv目录所遇到的问题总结
- Team Foundation Server 安装时遇到的问题与解决方法总结
- JavaScript URL传值过程中遇到的问题及知识点总结
- vs2010转vs2012工程 遇到的问题总结
- [置顶] 【办公采购系统】系统中遇到的问题汇总(三)——DropDownList控件使用总结
- 【转】ArcGIS Server 10.1发布要素服务时遇到的数据库注册问题总结(一)
- cocoapods 一些基本问题遇到总结
- CocoaPods 配置环境遇到的 一些问题总结
- maven和gradle打war包遇到的问题及总结
- 最近用了IE6下的滤镜,遇到的几个问题总结:
- Ubuntu 12.04 下安装ssh 服务遇到的问题以及总结