0

我有一个与主窗体 (UI) 并行运行的线程。它所做的(目前)只是每秒增加一个计数器。我想在 Windows 窗体中使用标签显示计数器的值。那可能吗?当我尝试以下代码时,在 ShowValue 方法中出现编译错误。我必须将 ShowValue 声明为“静态”,以便我可以从后台线程调用它。但如果我这样做,我就不能使用“这个”。访问 ShowValue Form1 中的标签。这是正确的方法吗?任何提示将不胜感激,谢谢!

    private void count_secs()
    {
        while (!stopThread)
        {
            if (stopThread)
            {
                break;
            }
            num2++;                      // increment counter
            Form1.ShowValue(num2);       // display the counter value in the main Form
            try
            {
                Thread.Sleep(1000);      // wait 1 sec.
            }
            catch (ThreadInterruptedException)
            {
                if (stopThread)
                {
                    break;
                }
            }
        }
    }

然后在我的 Form1 课程中,我有:

  public static void ShowValue(int num)
  {
        this.label7.Text = num.ToString();    
        // compiler error here: "Keyword 'this' is not valid in a static method.

  }
4

5 回答 5

1

您不能this.label7在静态方法中引用局部变量 ( )ShowValue(int num)

您的方法应如下所示:

public void ShowValue(int num)
  {

       if(label7.InvokeREquired)
       {
           Action a = () => ShowValue(num);
           label7.Invoke(a);
       }
       else
        this.label7.Text = num.ToString();    

  }

在这段代码中,用一个实例替换对表单的静态调用:

   private void count_secs()
    {
         var frm = new Form1(); //create instance
         frm.Show(); // show form

        while (!stopThread)
        {
            if (stopThread)
            {
                break;
            }
            num2++;                      // increment counter

            //use form instance
            frm.ShowValue(num2);       // display the counter value in the main Form
            try
            {
                Thread.Sleep(1000);      // wait 1 sec.
            }
            catch (ThreadInterruptedException)
            {
                if (stopThread)
                {
                    break;
                }
            }
        }

编辑

您可能想要在方法之外标记表单实例count_secs()

于 2013-05-08T07:18:46.233 回答
1

您不能从不同的线程随机访问 GUI 元素。对您的问题的简短回答是:使用现有结构。

  • 如果您只想经常做某事,请使用Timer。它会在时间到时通知您的主线程(即“拥有”GUI),您可以在那里更新 GUI 元素。
  • 如果您真的想创建自己的线程,请使用Backgroundworker。它将提供线程安全事件,您可以从中更新您的 GUI 元素。
于 2013-05-08T07:20:51.127 回答
1

您的第一个问题是获取 Form 实例,如果您的调用表单上没有 Form 实例,那么您会导致Application.OpenForms属性如下:

Form1 frm = Application.OpenForms["Form1"] as Form1;
if(frm != null)
    frm.ShowValue(num2);

您的第二个问题是您需要将方法修改为实例方法并将其从跨线程异常中保存,修改如下:

public void ShowValue(int num)
{
    if (label7.InvokeRequired)
    {
        label7.BeginInvoke((MethodInvoker)delegate { label7.Text = num.ToString(); });
    }
    else
    {
        label7.Text = num.ToString();
    }
} 
于 2013-05-08T07:22:42.793 回答
0

It's not mandatory to make the ShowValue function static. Leave it as non static and replace your line of logic Form1.ShowValue(num2) with following code.

 if (label1.InvokeRequired)
       label1.BeginInvoke(new Action(() => ShowValue(num2)));
 else
      label1.Invoke(new Action(() => ShowValue(num2)));
于 2013-05-08T07:44:15.063 回答
0

两个问题:

  1. 您不能使用this来自静态上下文的引用。
  2. 您无法从后台线程更新您的 UI。

解决方案:

  1. 将方法标记ShowValue为实例方法(即摆脱static
  2. 使用后台工作人员或阅读这个问题,它很好地解释了它
于 2013-05-08T07:19:30.460 回答