如何在单独的线程中完成操作时触发?

时间:2014-05-19 09:58:00

标签: c# multithreading winforms cursor controls

EDIT2:这不仅仅是一个跨线程的问题。我可以根据上面的链接更新控件,但它不适用于Cursor或toolStrip。不工作意味着不工作。我收到通常的错误消息,控件是在另一个线程中创建的,因此无法修改。 Invoke不是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";
    }));
}

1 个答案:

答案 0 :(得分:0)

谢谢Marc Gravell的想法

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