欢迎来到天天文库
浏览记录
ID:14888595
大小:83.00 KB
页数:5页
时间:2018-07-30
《c#跨线程访问控件》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、C#跨线程访问控件在用CS结构开发系统时,我们常会使用到多线程来处理程序,其中一个就是使用跨线程访问控件或设置控件属性。如果这样,在调试时会提示出错,不能在其它线程中修改创建控件的线程的控件的值。这是因为.net2.0以后加强了安全机制,不允许在winform中直接跨线程访问控件的属性。我们先看一下传统的程序:设计界面如下:在窗体中添加一个Label控件(用来显示时间)图1源程序:usingSystem;usingSystem.Windows.Forms;usingSystem.Threading;namespaceKingCh
2、at{publicpartialclassSystemLogin:DevExpress.XtraEditors.XtraForm{publicSystemLogin(){InitializeComponent();}privatevoidSystemLogin_Load(objectsender,EventArgse){ThreadnewThread=newThread(newThreadStart(threadFuntion));newThread.IsBackground=true;newThread.Start();}pr
3、ivatevoidthreadFuntion(){while(true){this.label1.Text=DateTime.Now.ToString();Thread.Sleep(1000);}}}}当调试上面的程序是会提示出错:图2如果你是直接运行程序生成的可执行文件就得到得到如下界面:图3原因是:.NET原则上禁止跨线程访问控件,因为这样可能造成错误的发生。那么我们有什么方法解决C#跨线程访问控件问题:1)禁止编译器对跨线程访问作检查,可以实现访问,但是出不出错不敢保证;2)推荐的解决方法是采用代理,用代理方法来间接操作不
4、是同一线程创建的控件。解决方案一:利用Control.CheckForIllegalCrossThreadCalls=false;加入这句代码调试时也不会提示出错,可以正常执行下面的程序。这句代码就是说在这个类中我们不检查跨线程的调用是否合法(如果没有加这句话运行也没有异常,那么说明系统以及默认的采用了不检查的方式)。然而,这种方法不可取。我们查看CheckForIllegalCrossThreadCalls这个属性的定义,就会发现它是一个static的,也就是说无论我们在项目的什么地方修改了这个值,他就会在全局起作用。而且像这
5、种跨线程访问是否存在异常,我们通常都会去检查。如果项目中其他人修改了这个属性,那么我们的方案就失败了,我们要采取另外的方案。具体做法如下:在窗体的Load方法中加入代码,其他不变privatevoidSystemLogin_Load(objectsender,EventArgse){Control.CheckForIllegalCrossThreadCalls=false;ThreadnewThread=newThread(newThreadStart(threadFuntion));newThread.IsBackground
6、=true;newThread.Start();}解决方案二:就是使用delegate和invoke来从其他线程中控制控件信息。源代码如下:usingSystem;usingSystem.Windows.Forms;usingSystem.Threading;namespaceKingChat{publicpartialclassSystemLogin:DevExpress.XtraEditors.XtraForm{privatedelegatevoidDelegateFunction();//代理publicSystemLog
7、in(){InitializeComponent();}privatevoidSystemLogin_Load(objectsender,EventArgse){Threadthread=newThread(CrossThreadFlush);thread.IsBackground=true;thread.Start();}privatevoidCrossThreadFlush(){while(true){Thread.Sleep(1000);ThreadFunction();}}privatevoidThreadFunctio
8、n(){if(this.label1.InvokeRequired)//等待异步{DelegateFunctiondf=newDelegateFunction(ThreadFunction);this.Invoke(df);//通过代理调用刷新方法}else{t
此文档下载收益归作者所有