添加进度条

发布于 2024-12-06 12:48:36 字数 671 浏览 0 评论 0原文

我有一个使用一个类的 Windows 窗体应用程序(其名称为 Parser) 该表单有一个按钮,当我单击 Windows 表单应用程序按钮时,它会调用解析器类方法之一。

此方法只是逐行读取文本文件并将每一行写入单独的文件...

我想在表单中添加一个进度条以显示进度(它是一个非常大的文件)

任何想法如何做到这一点?我在 Parse class 2 属性中,第一个属性表示文件中的行数,第二个属性表示已检查的行数。

这是我的 button2_Click 函数

private void button2_Click(object sender, EventArgs e)
{
      if (this.textBox1 != null & this.textBox2 != null)
      {
           inst.init(this.textBox1.Text, this.textBox2.Text);
           //this.progressBar1.Show();

           inst.ParseTheFile();
           System.Windows.Forms.MessageBox.Show("Parsing finish successfully"); 
       }
}

I have an a windows form application that use one class (its name is Parser)
this form has a button and when i click on the windows form application button it call one of the parser class method .

this method simply read text file line after line and write each line to separate file...

i would like to add a progress bar to the form in order to show the progress( it is a very large file )

any idea how to do that? I have in the Parse class 2 property one for the number of line in the file and the second how much lines already checked.

here is my button2_Click function

private void button2_Click(object sender, EventArgs e)
{
      if (this.textBox1 != null & this.textBox2 != null)
      {
           inst.init(this.textBox1.Text, this.textBox2.Text);
           //this.progressBar1.Show();

           inst.ParseTheFile();
           System.Windows.Forms.MessageBox.Show("Parsing finish successfully"); 
       }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

入怼 2024-12-13 12:48:36

您可以这样做:

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        var lines = File.ReadLines(@"D:\test.txt");
        var count = lines.Count();

        for(int i = 0; i < count; i++)
        {
            // some parse work
            Invoke(new Action(() =>
            {
                progressBar1.Value = (i * 100) / count;
            }));
        }
    });
}

在上面的示例中,它只是创建一个后台线程,以便不阻塞 UI 线程,直到调用 Invoke 方法。
为了使用当前线程不是其所有者的 Control 进行操作,Invoke 方法是必需的。它需要一个委托,并在拥有 Control 的线程上运行该委托。

如果解析这些行是一项耗时的任务,您甚至可以尽可能使 foreach 循环并行。一个例子:

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        var lines = File.ReadLines(@"D:\test.txt");
        var count = lines.Count();

        Parallel.For(0, count, i =>
        {
            // some parse work
            Invoke(new Action(() =>
            {
                progressBar1.Value = (i * 100) / count;
            }));
        });
    });
}

You could do:

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        var lines = File.ReadLines(@"D:\test.txt");
        var count = lines.Count();

        for(int i = 0; i < count; i++)
        {
            // some parse work
            Invoke(new Action(() =>
            {
                progressBar1.Value = (i * 100) / count;
            }));
        }
    });
}

In the example above, it simply creates a background thread in order not to block the UI thread, until the Invoke method is called.
The Invoke method is necessary, in order to manipulate with a Control that the current thread isn't the owner of. It takes a delegate, and runs this delegate on the thread that owns the Control.

You could even go as far, as making the foreach loop parallel, if it's a time consuming task to parse the lines. An example:

private void button1_Click(object sender, EventArgs e)
{
    ThreadPool.QueueUserWorkItem((obj) =>
    {
        var lines = File.ReadLines(@"D:\test.txt");
        var count = lines.Count();

        Parallel.For(0, count, i =>
        {
            // some parse work
            Invoke(new Action(() =>
            {
                progressBar1.Value = (i * 100) / count;
            }));
        });
    });
}
冰葑 2024-12-13 12:48:36

通常你应该继续写一些你已经尝试过的内容。
因为我认为您更倾向于“开始”一侧,所以我建议您查看 BackgroundWorker 及其 ProgressChanged 事件/系统(这里是一个 简介

当然你必须移动你的 ParseTheFile 代码 。对于更高级的东西,

有几个选项:

  • ParseTheFile 添加一个参数(例如 Action) 用于设置进度
  • 返回 IObservable 来自您的 ParseTheFile ,指示进度
  • 使用一些静态服务 ParseTheFile 用于指示进度(不建议)
  • ...(我确信其他人会找到更多选项)

(请注意,大多数选项都需要使用 Control.Invoke 返回 UI 线程来设置进度条值 - 如果文件那么大,我建议您使用另一个线程)

对于初学者我会选择后台工作人员 - 恕我直言,如果你不想在第一次运行时变得扎实(设计模式/原则),那也没关系;)

normaly you should go on and write some on what you allready tried.
As I think you are more on the *begining" side I would advise looking into the BackgroundWorker and its ProgressChanged event / system (Here is a intro to it).

Of course you have to move your ParseTheFile-code into this.

For more advanced stuff there are a few options:

  • add a parameter to the ParseTheFile (for example a Action) that is used to set the progress
  • return a IObservable from your ParseTheFile that indicates the progress
  • use some static service ParseTheFile is using to indicate the progress (not adviced)
  • ... (I'm sure other poeple will find a lot more options)

(Please not that most of this options require to use Control.Invoke to get back to your UI-Thread for setting progress-bars value if you use another thread - and I would advise you using another thread if the file is that big)

For starter I would go with the backgroundworker - IMHO it's fine if you don't want to go SOLID (desing patterns/priciples) on your first run ;)

_畞蕅 2024-12-13 12:48:36

只需使用数学来计算百分比
就像:

//While Reading
NumOfLines++;
int Percentage = (NumOfLines * 100) / TotalLines ;
ProgressBar.Value = Percentage;

并且可能放入 int.ParseTheFile();进入后台工作人员和/或线程内。

Just use Math to Calculate Percentage
Like :

//While Reading
NumOfLines++;
int Percentage = (NumOfLines * 100) / TotalLines ;
ProgressBar.Value = Percentage;

And probably put int.ParseTheFile(); into a Background Worker and/or within a Thread.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文