【问题标题】:How to trigger when action in separate thread is complete?单独线程中的操作完成时如何触发?
【发布时间】:2014-05-19 09:57:59
【问题描述】:

EDIT2:这不仅仅是一个跨线程问题。我可以根据上面的链接更新控件,但它不适用于 Cursor 或 toolStrip。不工作意味着不工作。我收到通常的错误消息,即控件是在另一个线程中创建的,因此无法修改。调用不是 toolStrip 的选项。

单击按钮时,我会在单独的线程中启动一些操作。这是必要的,因为它可能需要一段时间,而且我的表格通常会被冻结。我的问题是我必须修改几个控件,并在最后将它们设置回来,这是我无法从工作线程中完成的。如何解决?

private void button1_Click(object sender, EventArgs e)
{
    Cursor.Current = Cursors.WaitCursor;
    toolStripStatusLabel1.Text = "Working...";
    Thread thread = new Thread(query);
    thread.Start();
}
private void query()
{
    //actions
    //here I need to set the cursor back to default
    Cursor.Current = Cursors.Default; //but this is obviously not working
    //and I have to set the label text to be "done"
    //which is not working as well as invoke is not an option for toolStrips
}

所以我需要一些解决方案来完成上述操作。也许一些后台工作人员会在查询()线程和操作完成后“密切关注”它?

EDIT3:我可以使用以下代码修改任何控件的任何属性,除了 toolStrip:

delegate void SetControlValueCallback(Control oControl, string propName, object propValue);
    private void SetControlPropertyValue(Control oControl, string propName, object propValue)
    {
        if (oControl.InvokeRequired)
        {
            SetControlValueCallback d = new SetControlValueCallback(SetControlPropertyValue);
            oControl.Invoke(d, new object[] { oControl, propName, propValue });
        }
        else
        {
            Type t = oControl.GetType();
            PropertyInfo[] props = t.GetProperties();
            foreach (PropertyInfo p in props)
            {
                if (p.Name.ToUpper() == propName.ToUpper())
                {
                    p.SetValue(oControl, propValue, null);
                }
            }
        }
    }

解决方案:感谢 Marc Gravell 的想法

private void query()
{
    //actions
    Invoke((Action)(() =>
    {
        Cursor.Current = Cursors.Default;
        toolStripStatusLabel1.Text = "done";
    }));
}

【问题讨论】:

    标签: c# multithreading winforms cursor controls


    【解决方案1】:

    感谢 Marc Gravell 的想法

    private void query()
    {
        //actions
        Invoke((Action)(() =>
        {
            Cursor.Current = Cursors.Default;
            toolStripStatusLabel1.Text = "done";
        }));
    }
    

    【讨论】:

      猜你喜欢
      • 2020-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多