线程调用窗口表单控件

时间:2014-02-28 08:58:03

标签: c# multithreading winforms thread-safety

我想让线程可以调用窗口窗体控件。我做到了:

delegate void SetTextCallback(String str, int i);
private void SetText(string text, int i)
{
    // InvokeRequired required compares the thread ID of the 
    // calling thread to the thread ID of the creating thread. 
    // If these threads are different, it returns true. 
    if (this.label2.InvokeRequired)
    {
        SetTextCallback d = new SetTextCallback(SetText);
        this.Invoke(d, new object[] { text,i});
    }
    else
    {
        switch (i)
        {
            case 1:
                this.label1.Text = text;
                break;
            case 2:
                this.label2.Text = text;
                break;
        }

    }
}

但它似乎太长了,因为我想打电话给许多表格obj (label1,label2,textbox,...) - >案例1,2,3,4,5,我们将很多案例

有更好的方法吗? 在SetText中输出 int i (字符串文本,int i)

另一种方式

不使用开关(i)来了解哪个obj需要更改文字

=====更新=====

这是线程中的代码

SetText("This text for the first label",1);
SetText("This text for the second label",2);

1 个答案:

答案 0 :(得分:4)

我为此使用了几种扩展方法。

public static class ControlExtensions
{
    public static void SafeInvoke(this Control control, Action action) 
    {
        if(control.InvokeRequired) 
        {
            control.BeginInvoke(action);
        }
        else 
        {
            action();
        }
    }
}

然后使用它,就像这样。

public void TreeCompleted(bool completed)
{
    this.SafeInvoke(() =>
    {
        if(completed) 
        {
            DiagnosisTree = treeBranchControl1.GetDiagnosisTree(null);

            pctLoader.Visible = false;
            btnSelectDiagnosis.Visible = false;
            lblDiagnosis.Visible = true;
            treeBranchControl1.Visible = true;
        }
        else 
        {
            DiagnosisId = 0;
            DiagnosisTree = null;
        }
    });   
}

这是代码运行的表单或控件。

在您的情况下,您这样做:

public void SetText(string text, int i)
{
    this.SafeInvoke(() =>
    {
        switch (i)
        {
            case 1:
                this.label1.Text = text;
                break;
            case 2:
                this.label2.Text = text;
                break;
        }
    });   
}