本文介绍了我如何从另一个线程访问变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

获取错误:跨线程操作无效:控制'label1'从其创建线程以外的线程访问。



代码:

  using System; 
使用System.Collections.Generic;
使用System.ComponentModel;
使用System.Data;
使用System.Drawing;
使用System.Linq;
使用System.Text;
使用System.Threading.Tasks;
使用System.Threading;
使用System.Windows.Forms;

namespace WindowsFormsApplication2
{
public partial class Form1:Form
{
string CONNECTING =Connecting to server ...;
字符串GETTING_DATA =获取数据...;
string CONNECT_FAIL =无法连接!;
字符串CONNECT_SUCCESS =建立连接!;

public Form1()
{
InitializeComponent();

$ b $ private void Form1_Load(object sender,EventArgs e)
{
Thread t1 = new Thread(run);
t1.Start();
}

public void run(){
label1.Text = CONNECTING;
}
}
}

如何正确解决此问题?我已经尝试过使用 CheckForIllegalCrossThreadCalls = false; 但是这显然会导致错误。



我也想知道如何停止线程,因为它不能在该函数之外访问。



预先感谢!

解决方案

从不同线程访问控件



WinForms App 你可以直接从它创建的线程访问 Control
要执行此类任务,您需要使用属性来查看是否必须使用命令强制从原始线程调用操作。


可以从任何线程访问的公共方法像这样:

  public void run(){
if(label1.InvokeRequired)//是否调用此方法从另一个线程
this.Invoke(new MethodInvoker(()=> label1.Text = CONNECTING));
else //很酷,这是原始线程,推导出
label1.Text = CONNECTING;
}



但是如果您绝对确信<$只会从线程调用c $ c> run()方法,考虑不要检查 InvokeRequired 并立即调用调用


更多信息:


停止正在进行的线程




  • Simples使用方法 Thread 。这会抛出异常,迫使它停止以前的任何事情。这对于那些不进行任何长处理的线程来说非常棒,因此停止它不会造成任何问题。

  • 如果你在你的线程中做了proccesing,意味着你不能在中间停下来,那么我建议你使用一个布尔值来表示线程必须尽快取消。






  private bool isCancelRequired = false; 
public void run(){
while(true){
// do long processing ..
if(isCancelRequired)
break;




$ b $ ul
  • 更高级的方法:


  • Getting error: Cross-thread operation not valid: Control 'label1' accessed from a thread other than the thread it was created on.

    Code:

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Threading;
    using System.Windows.Forms;
    
    namespace WindowsFormsApplication2
    {
        public partial class Form1 : Form
        {
            string CONNECTING = "Connecting to server...";
            string GETTING_DATA = "Getting data...";
            string CONNECT_FAIL = "Failed to connect!";
            string CONNECT_SUCCESS = "Connection established!";
    
            public Form1()
            {
                InitializeComponent();
            }
    
            private void Form1_Load(object sender, EventArgs e)
            {
                Thread t1 = new Thread(run);
                t1.Start();
            }
    
            public void run() {
                label1.Text = CONNECTING;
            }
        }
    }
    

    How do I properly fix this? I've tried using CheckForIllegalCrossThreadCalls = false; but that obviously causes errors.

    I'd also like to know how I can stop the thread, since it can't be accessed anymore outside of that function.

    Thanks in advance!

    解决方案

    Accessing a control from different threads

    In WinForms App you can ony access directly a Control from the thread it was created.To do such a task you will need to use InvokeRequired property of a control to see if you must use Invoke inorder to force a call of the action from the original thread.

    A public method that might be accessed from any thread including the original would look like this:

    public void run() {
        if (label1.InvokeRequired) //Is this method being called from a different thread
            this.Invoke(new MethodInvoker(()=> label1.Text = CONNECTING));
        else //it's cool, this is the original thread, procceed
            label1.Text = CONNECTING;
    }
    


    But if you are absolutly sure that run() method will be called only from the thread, consider not even checking if InvokeRequired and immediatly call Invoke

    Further information: http://msdn.microsoft.com/en-us/library/ms171728(v=vs.80).aspx

    Stopping a thread in progress

    • Simples is to use t1.Abort(); method of a Thread. This will throw and exception forcing it to stop where ever it was. this is great for threads that do not do any long processing so stopping it won't cause any problems.

    • If you do do proccesing in your thread, which means you can't just stop it in the middle then I suggest you to use a boolean that will indicate that the thread must cancel ASAP.

    private bool isCancelRequired = false;
    public void run() {
         while(true) {
             //do long processing..
             if (isCancelRequired)
                break;
         }
    }
    

    这篇关于我如何从另一个线程访问变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

    08-13 10:15