【问题标题】:how to update process bar in c# in another thread which are execute in another class [closed]如何在另一个类中执行的另一个线程中更新c#中的进程栏[关闭]
【发布时间】:2014-06-23 17:13:51
【问题描述】:

我正在处理 Windows 窗体 我想从另一个线程更新进度条 这个线程执行另一个类的代码 喜欢:

 class form1
  {
         //start thread in this class
        //which are execute second class method
  }
  class second
  {
     //in this class i want to update progress bar
   }

如果对一个文件的处理完成,那么我正在处理文件并一一读取“第二类”中的文件,然后我想更新进程栏(整个进程在另一个线程而不是 ui 线程中运行)。我怎样才能做到这一点。 谢谢

【问题讨论】:

    标签: c# multithreading user-interface progress-bar


    【解决方案1】:

    最好的方法是使用BackgroundWorker 对象。有一个完整的代码示例说明如何使用here

    否则,您需要使用Invoke 来更新其他类中的进度条。这将减轻您可能遇到的跨线程错误。

    【讨论】:

    • 我尝试了这两种方法,但 BackgroundWorker 对象在另一个类中不起作用,并且调用和 begininvoke 给出此异常“在创建窗口句柄之前无法在控件上调用 Invoke 或 BeginInvoke”。跨度>
    • 为什么要尝试更新尚未实例化的表单中的进度条?
    • 我给你看一些演示代码 private void button1_Click(object sender, EventArgs e) { // await Task.Run(() => cnt());第二个=新的第二个(); ThreadStart theprogress = new ThreadStart(a.cnt);线程 startprogress = new Thread(theprogress); startprogress.Name = "更新进度条"; startprogress.Start(); } public void UpdateProgress() { progressBar1.Value += 1; }
    • 第二类 { public void cnt() { Form1 af = new Form1();更新栏 ast = 新更新栏(af.UpdateProgress);诠释 i = 0; while (true) { if (i % 10 == 0) { af.progressBar1.Invoke(ast); } if (i == 100) { 休息; } 我++;线程.睡眠(100); } }
    • 请不要将代码放入 cmets。如您所见,无法阅读。改为编辑您的问题。
    【解决方案2】:

    如果你想自己调用,你可以这样做:

    //This goes in your Form1
        private void button1_Click(object sender, EventArgs e)
        {
            Thread t = new Thread(WorkThread);
            t.Start();
        }
    
        private void WorkThread()
        {
            DoSomeWork w = new DoSomeWork();
    
            w.Work();
    
            while (w.progress < 100)
            {
                UpdateFromThread(w.progress);
                Thread.Sleep(100);
            }
        }
    
        private void UpdateFromThread(int progress)
        {
            if (this.InvokeRequired)
            {
                MethodInvoker MyDelegate = delegate { UpdateFromThread(progress); };
                this.Invoke(MyDelegate);
            }
            else
            {
                progressBar1.Value = progress;
            }
        }
    
    //Class to do some work.
    class DoSomeWork
    {
    
        public int progress { get; set; }
    
        public DoSomeWork()
        {
            progress = 0;
        }
    
        public void Work()
        {
            Thread t = new Thread(WorkThread);
            t.Start();
        }
    
        private void WorkThread()
        {
            for (int i = 0; i < 100; i++)
            {
                progress += 1;
                Thread.Sleep(250);
            }
        }
    }
    

    您没有具体说明您想要做什么,但这是总体思路。 BackgroundWorkers 绝对更干净。

    【讨论】:

    • 您不应该仅仅为了定期更新进度而创建第二个线程。如果确实需要限制进度更新(通常不需要),那么至少您应该使用计时器。
    • 两件事我想先问你为什么你添加另一个线程它不可能在同一个线程中?当我关闭我的表单时,我得到这个异常“无法访问已处理的对象。”
    • 在这一行“this.Invoke(MyDelegate);”
    • 好的,我明白了,谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 2021-05-04
    • 1970-01-01
    • 2012-06-10
    • 2022-12-31
    • 1970-01-01
    相关资源
    最近更新 更多