进度栏选框与运行过程 [英] Progress bar marquee with running process

查看:76
本文介绍了进度栏选框与运行过程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请帮我解决我的问题。



例如,我想创建一个计数为100的标签文本 - (这可能超过100) )

在同一个过程中,我想在Label Text更新时显示一个进度条。



因为我不喜欢我不想报告进度,这就是为什么我使用Marquee和for循环以下就是这个过程的例子。



我在下面遇到错误

Hi, Please help me with my problem.

For example, I want to create a Label Text that counts into 100 - (this can be more than 100)
At the same process, as it is counting I want to show a Progress Bar while Label Text is Updating.

Since I don't want to report the progress, that's why I'm using Marquee and for loop below is just and example of the process.

I encountered below error in

this.label1.Text += string.Format("{0}. This is a test.", i);





一个例外发生了'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException'



我尝试了什么:





An exception 'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException' occurred

What I have tried:

private void button1_Click(object sender, EventArgs e)
       {
           button1.Enabled = false;
           progressBar1.Style = ProgressBarStyle.Marquee;
           progressBar1.MarqueeAnimationSpeed = 50;

           BackgroundWorker bw = new BackgroundWorker();
           bw.DoWork += bw_DoWork;
           bw.RunWorkerCompleted += bw_RunWorkerCompleted;
           bw.RunWorkerAsync();
       }

       void bw_DoWork(object sender, DoWorkEventArgs e)
       {
           // INSERT TIME CONSUMING OPERATIONS HERE
           // THAT DON'T REPORT PROGRESS
           for (int i = 1; i <= 100; i++)
           {
               this.label1.Text += string.Format("{0}. This is a test.", i);

           }
           Thread.Sleep(100);
       }

       void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
       {
           progressBar1.MarqueeAnimationSpeed = 0;
           progressBar1.Style = ProgressBarStyle.Blocks;
           progressBar1.Value = progressBar1.Minimum;

           button1.Enabled = true;
           MessageBox.Show("Done!");
       }

推荐答案

您应该先阅读有关BackgroundWorker的文档,然后再使用它来正确理解它是如何工作的应该使用。



BackgroundWorker类(System.ComponentModel) [ ^ ]



如何:对Windows窗体控件进行线程安全调用 [ ^ ]



以下是一些类似的问题:

c# - 使用backgroundworker窗体表格时的CrossThreadMessagingException - Stack Overflow [ ^ ]

多线程 - C#线程问题 - 堆栈溢出 [ ^ ]



在您的情况下,您通常希望启用进度报告,然后实施处理程序来报告进度。

BackgroundWorker.ReportProgress方法(Int32)(System.ComponentModel) [ ^ ]



通常,我会计算pe内部 DSoWork 处理程序中的rcentage,仅在百分比(作为整数)发生更改时报告进度。这样,您可以确保在显示进度条时不会将UI更新100次以上。



顺便提一下,有一个允许传递UserState的版本,如果要报告除百分比之外的其他内容,可以使用该版本。这比直接使用调用更简单,更清晰。



如果你报告进度,通常效果很好几百次。如果你有几千个更新,那么你需要优化线程之间的通信以减少跨线程调用的开销。
You should read the documentation on BackgroundWorker before using one to properly understand how it works and should be used.

BackgroundWorker Class (System.ComponentModel)[^]

How to: Make Thread-Safe Calls to Windows Forms Controls[^]

Here are some similar questions :
c# - CrossThreadMessagingException while using backgroundworker windows forms - Stack Overflow[^]
multithreading - C# threading issue - Stack Overflow[^]

In your case, you usually want to enable progress reporting and then implement an handler to report progress.
BackgroundWorker.ReportProgress Method (Int32) (System.ComponentModel)[^]

Usually, I would compute the percentage inside DSoWork handler and only report progress if the percentage (as an integer) has changed. That way, you ensure that you don't update the UI more than 100 times which is adequate when a progress bar is displayed.

By the way, there is a version that allows to pass an UserState which could be used if you want to report something else than percentage. This is somewhat simpler and clearer than using Invoke directly.

It generally works quite well if you report progress up to a few hundreds of time. If you have many thousand updates, then you somehow need to optimize communications between threads to reduce the overhead of cross-thread calls.


我不确定你为什么设置progressBar1.Value = progressBar1.Maximum那里 - 它可能是我不知道的关于Marquee风格的东西..据说,我会期待像



I'm not sure why you're setting progressBar1.Value = progressBar1.Maximum there - it may be something I dont know about the Marquee style .. that being said, I would have expected something like

progressBar1.BeginInvoke(
  new Action( () =>
    {
      progressBar1.Value = i;
    }
  ));




'for loop'里面
- 我没看到你在哪里更新进度条的价值



..为什么不采取这个





inside your 'for loop' - I dont see where else you're updating the value for the progress bar

[edit] .. why not take this

for (int i = 1; i <= 100; i++)
{
  this.label1.Text += string.Format("{0}. This is a test.", i);
  Thread.Sleep(10000);
}





并将其设为这个





and make it this

for (int i = 1; i <= 100; i++)
{
  this.label1.Text += string.Format("{0}. This is a test.", i);
  progressBar1.Value = i; 
  Thread.Sleep(10000);  // Not sure you need to delay for this long 
}





除非我不知道你想做什么/你的问题是什么



[/ edit]



unless somehow Ive missed what your trying to do/what your problem is

[/edit]


这篇关于进度栏选框与运行过程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆