【问题标题】:C# update UI from different class/thread [duplicate]C#从不同的类/线程更新UI [重复]
【发布时间】:2017-04-11 14:17:20
【问题描述】:

大家早上好,我正在尝试用 C# 编写一些应用程序,我想从另一个线程和类更新 UI(在本例中为进度条)。

但我无法让它工作,我用谷歌搜索并四处搜索,但恐怕我就是不明白。我有一个 Windows 窗体应用程序,当我单击一个按钮时我会启动一个线程,并且我想在这个线程的某个地方更新我的 UI。

我要么得到: 非静态字段、方法或属性需要对象引用 或其他线程正在创建的对象方向上的东西。 (在我尝试在 fileReader 中调用 Form1.UpdateProgressBar(value); 的位置)。

我没有面向对象编程的经验,我通常坚持使用 C。如果有人能告诉我正确的方法,我会很高兴。

Edit_1:好吧..错误的组合,如果我没有静态问题,到目前为止的答案可能会有所帮助。并且通过使整个类静态来解决静态问题会自行产生另外 X 数量的错误,包括:

静态类不能有实例构造函数

namespace TestCode
{

  public partial class Form1 : Form
  {
    static fileReader SourceReader;
    public Thread SearchThread { get; set; }

    public Form1()
    {
        InitializeComponent();

    }

    private void button1_Click(object sender, EventArgs e)
    {
        folderBrowserDialog1.ShowDialog();
        Console.WriteLine(folderBrowserDialog1.SelectedPath);

        this.SearchThread = new Thread(new ThreadStart(this.ThreadProcSafe));
        this.SearchThread.Start();
    }


    public void UpdateProgressBar( int value)
    {

       progressBar1.Value =value;

    }

    private void ThreadProcSafe()
    {
        SourceReader = new fileReader(folderBrowserDialog1.SelectedPath);
    }
  }
}

第 2 类:

     namespace TestCode
     {
         class fileReader
         {

             public fileReader(String path)
             {
                int value = 20;
                /*Do some stuff*/
                  Form1.UpdateProgressBar(value);

             }

          }

     }

【问题讨论】:

  • 您的 fileReader 类不是静态的,这就是为什么编译器说在调用它的构造函数之前需要对该类的引用。
  • 这是一个糟糕的设计。 fileReader 不应依赖于 Forms。查看TaskIProgress<T> 的用法以获得更好的进度通知。示例:blogs.msdn.microsoft.com/dotnet/2012/06/06/…

标签: c# multithreading winforms


【解决方案1】:

检查是否需要调用和需要inf,然后使用控件调用函数:

public void UpdateProgressBar( int value)
{
   if(progressBar1.InvokeRequired){
       progressBar1.Invoke(new MethodInvoker(() => progressBar1.Value=value));
   }else{
       progressBar1.Value =value;
   }
}

【讨论】:

    【解决方案2】:

    您可以在尝试从另一个类修改 UI 时使用 MethodInvoker,如下所示:

    ProgressBar progressBar = Form1.progressBar1;
    MethodInvoker action = () => progressBar.Value = 80;
    progressBar.BeginInvoke(action);
    

    当您在不同的线程中工作时可以使用它(例如 Task):

    progressBar1.Invoke((Action)(() => progressBar1.Value=50))
    

    但请考虑您帖子中的 cmets。 fileReader中不需要依赖Forms

    旁注:我不知道你怎么没在这里找到你的问题:

    how to update a windows form GUI from another class?

    How to update the GUI from another thread in C#?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2012-12-28
      • 1970-01-01
      • 2014-05-11
      相关资源
      最近更新 更多