跨线程操作无效:从创建它的线程以外的线程访问控制“文本框”

eAg*_*gle 1 c# cloud multithreading delegates timer

我需要一些帮助。我开始使用 c#,但对事件处理和线程还不是很熟悉。作为一个初学者,随着时间和接触的增加,我想了解更多关于这些高级主题的知识并进行改进,并希望这里的所有人都能帮助我。

我遇到了“跨线程操作无效:从创建它的线程以外的线程访问控制‘名为 stackStatus’的文本框控件”的问题。我一整天都在尝试解决问题,但根本无济于事。我被困住了。:-( 程序遇到异常,无法继续顺利执行。

我已阅读以下主题并尝试了一些事情,但我想我仍然缺少一些东西。如果有人能在这里帮助我,我将不胜感激。谢谢。

跨线程操作无效:从创建它的线程以外的线程访问控制

跨线程操作无效:从创建它的线程以外的线程访问控制“textBox1”

这是代码的大部分部分:

  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();

    }
Run Code Online (Sandbox Code Playgroud)

Na*_*de 9

而不是做:

stackStatus.Text = "some text";
Run Code Online (Sandbox Code Playgroud)

尝试 :

stackStatus.Invoke((Action)delegate
{
    stackStatus.Text = "some text";
});
Run Code Online (Sandbox Code Playgroud)

请注意,不推荐在声明它们的线程之外进行 GUI 元素分配,因为控件可能随时不再可用。