线程间操作无效: 从不是创建控件的线程访问它的三种解决方法
转载请标明出处:Python Excellent的博客
线程的3种创建方式:
1、Task.Factory.StartNew(() => );
privatevoiduiButton1_Click(object sender,EventArgs e){
Task.Factory.StartNew(()=>Test1());}
2、new Task(() =>{});
privatevoiduiButton2_Click(object sender,EventArgs e){Task task2 =newTask(()=>{Test2();});
task2.Start();}
3、new Thread();
- 此为最基础方法 (入门级)
privatevoiduiButton3_Click(object sender,EventArgs e){//方式1:Thread TestThread =newThread(Test1);
TestThread.IsBackground =true;
TestThread.Start();//方式2:Thread thread1 =newThread(newThreadStart(Test1)){
IsBackground =true};
thread1.Start();}
方法一:异步委托线程中控件访问
- 运行效果如图所示* 先在按钮事件中创建一个Test1()线程* 在测试1中有两种方法可以访问窗体线程(首推荐)
privatevoiduiButton1_Click(object sender,EventArgs e){
Task.Factory.StartNew(()=>Test1());}publicvoidTest1(){//创建了一个异步委托线程//第一种方法 (推荐)this.BeginInvoke((MethodInvoker)delegate{try{
label1.Text ="方法1.1 列举测试";
MessageBox.Show("创建线程访问UI线程已完成");}catch(Exception ex){}});//第二种方法 (推荐)this.Invoke(newEventHandler(delegate{try{
label2.Text ="方法1.2 列举测试";
MessageBox.Show("创建线程访问UI线程已完成");}catch(Exception){}}));}
方法二:采用不同步的自由线程上下文的基类
- public SynchronizationContext UiContext //第一步全局声明
- UiContext = SynchronizationContext.Current; //第二部在public Form1()中实例化该对象即可
publicSynchronizationContext UiContext ;//UI主线程上下文publicForm1(){InitializeComponent();//方式二:实例化一个获取当前UI主线程上下文对象。
UiContext = SynchronizationContext.Current;}privatevoiduiButton2_Click(object sender,EventArgs e){Task task2 =newTask(()=>{Test2();});
task2.Start();}publicvoidTest2(){try{
Thread.Sleep(200);
UiContext.Post(e =>{
label1.Text ="方法二列举测试";
MessageBox.Show("创建线程访问UI线程已完成");},0);}catch(Exception){throw;}}
方法三:取消跨线程访问(不推荐)
** 取消跨线程访问(此为不安全操作)**
- Control.CheckForIllegalCrossThreadCalls = false; //在 public Form1() 函数或 Form1_Load() 中声明此代码即可
publicForm1(){InitializeComponent();//方式三:取消跨线程访问(不安全操作)
Control.CheckForIllegalCrossThreadCalls =false;}//按钮点击事件创建线程并开启线程privatevoiduiButton1_Click(object sender,EventArgs e){Thread thread1 =newThread(newThreadStart(Test)){
IsBackground =true};
thread1.Start();}publicvoidTest(){try{
Thread.Sleep(200);for(int i =0; i <10; i++){
Thread.Sleep(1000);// 1s间隔显示//在线程间访问操作窗体控件
label1.Text = String.Format("这是第{0}次举例测试", i);}//在线程间访问操作窗体控件
MessageBox.Show("创建线程访问UI线程已完成");}catch(Exception){throw;}}
本文转载自: https://blog.csdn.net/zylgxt/article/details/129547780
版权归原作者 Python Excellent 所有, 如有侵权,请联系我们删除。
版权归原作者 Python Excellent 所有, 如有侵权,请联系我们删除。