c# - 跨线程操作无效: Control 'textbox' accessed from a thread other than the thread it was created on

标签 c# multithreading timer delegates cloud

我需要帮助。我开始使用C#,对事件处理和线程处理还不太熟悉。作为初学者,随着时间和曝光度的提高,我想学习更多有关这些高级主题的知识,并且希望他们有所进步,并希望在座的所有人都能对我有所帮助。

我遇到了“跨线程操作无效:从创建该线程的线程之外的线程访问的控件'称为stackStatus'的文本框控件”的问题。我试图整天排除故障,但无济于事。我被困住了。 :-(程序遇到异常,无法继续平稳执行。

我已经阅读了以下主题并尝试了一些方法,但我想我仍然缺少一些东西。感谢有人可以在这里帮助我。谢谢。

Cross-thread operation not valid: Control accessed from a thread other than the thread it was created on

Cross-thread operation not valid: Control 'textBox1' accessed from a thread other than the thread it was created on

这是大部分代码:

  private void createCloud_Click(object sender, EventArgs e)
    {
        CreateCloud(); //start creation method
        stackStatus.Text = "Creating stack..."; //updates the cloud status textbox
        stackStatus.Refresh();
        Cursor.Current = Cursors.WaitCursor; //change the cursor to wait state
        Start_Describestack(); //call describe method to find out the status of cloud creation progress

        Task.Delay(12000); // wait 12s in case not ready

        Start_Describestack(); // call again describe method to find out the cloud creation progress status
        Cursor.Current = Cursors.Default; //put cursor on wait
        describeevents(); // call method to get all cloud creation event data and publish on the datagridview

    }



    private void Start_Describestack()
    {
        //method making use of timer to call 

        _timer = new System.Timers.Timer(15000);
        _timer.Elapsed += new ElapsedEventHandler(describeStack);
        _timer.Enabled = true;


    }

    delegate void describeStackCallBack(object sender, ElapsedEventArgs e);

    private void describeStack(object sender, ElapsedEventArgs e)
    {
        //this method makes api calls through cloudclient to describe the stack
        //this is where the "Cross-thread operation not valid: Control 'stackStatus' accessed from a thread other than the thread it was created on"


        var client = new cloudclient();
        var request2 = new StacksRequest();

        request2.Cloudstackname = stackid;

        try
        {
            var response = client.DescribeCloudStacks(request2);

            foreach (var stack in response.Stacks)
            {

            //something is wrong here but I do not know how to fix it. Please help
                if (this.stackStatus.InvokeRequired)
                {
                    describeStackCallBack d = new describeStackCallBack(describeStack);
                    this.Invoke(d, new object[] { sender, e });
                    stackStatus.Refresh();
                    describevents();
                }
                else
                {
                    stackStatus.Text = stack.StackStatus;
                    stackStatus.Refresh();
                    describeevents();
                }
            }
        }
        catch (Exception)
        {

            if (this.stackStatus.InvokeRequired)
            {
                describeStackCallBack d = new describeStackCallBack(describeStack);
                this.Invoke(d, new object[] { sender, e });

                stackStatus.Text = "Stack not found/Deleted";
            }
            else
            { stackStatus.Text = "Stack not found/Deleted"; }
        }

     describeevents();
    }

    private void describeevents()
    {


        var newclient = new cloudclient();
        var request3 = new eventrequest();

        request3.Cloudstackname = stackid;


            try
            {
                var response = newclient.eventstack(request3);
                dataGridView3.Rows.Clear();

                foreach (var events in response.sevents)
                {
                    dataGridView3.Rows.Add(events.Timestamp, events.ResourceStatus, events.ResourceType);
                }
            }
            catch (Exception)
            {
                dataGridView3.Rows.Clear();
                MessageBox.Show("Stack not ready!");
            }

        dataGridView3.Refresh();

    }

最佳答案

而不是做:

stackStatus.Text = "some text";

尝试 :
stackStatus.Invoke((Action)delegate
{
    stackStatus.Text = "some text";
});

请注意,不赞成在线程外或声明它们之外进行GUI元素分配,因为这些控件可能在任何时候都不再可用。

关于c# - 跨线程操作无效: Control 'textbox' accessed from a thread other than the thread it was created on,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43741059/

相关文章:

c# - WCF 服务标记基本类型时出错

c# - 如何覆盖数据列表以呈现为 div 而不是表格?

c# - 如果用户使用 Google 登录,ASP.NET Core Identity 2.0 SignoutAsync 不会注销用户

c++ - 此代码是从 vector 中添加和删除项目的线程安全方式吗?

c# - OpenQA.Selenium.WebDriverException : A exception with a null response was thrown and halts the selenium test run

c# - 使用游戏引擎 (Unity3D) 进行多线程?

c - PIT 不向 IRQ0 发送中断

javascript - 如何在 JavaScript 中编写倒数计时器?

python - 如何在 Python 中使用计时器解锁条件?

Python线程/守护进程