当前位置: 首页 > 知识库问答 >
问题:

如何创建循环百分比(处理)[c#]

干弘深
2023-03-14

示例:9999次做某事(可能超过)

for (int i = 1; i <= 9999; i++)
{
    // do something
    label1.content = 100*i/9999 + "%" ;
}

我想在label1上显示循环的百分比,当我编译时,我不能在几毫秒内做任何事情,我的标签只显示100%。有人知道吗,先生?非常感谢。

共有3个答案

西门凯康
2023-03-14

@mm8解决方案是可以的,但是从新线程到UI线程的每次并发往返都会延迟循环。

如果您希望循环尽早结束,而不会使用户界面膨胀(以及您的目标网络框架4.5或更高版本),您可以使用与旧DoEvents:任务等效的异步任务方法。产量().

    private async void Button_Click(object sender, RoutedEventArgs e)
    {
        for (int i = 0; i < 10000; i++)
        {
            //Do something
            //Simulate work with Task.Delay(millisecondos)
            Label1.Content = (i * 100 / 10000) + "%";
            await Task.Yield(); //give opportunity to dispatch other events
        }
    }

这个解决方案很简单,它是一个例子,说明了为什么异步并不总是需要多线程,正如这个答案和本文中所述

但是在放弃任务之间有一个权衡。屈服()并创建一个新的线程,如@mm8解决方案:

  1. Rest一下任务。如果工作可以分块完成,并且在每个分块中必须更新UI,那么收益()会更好。
  2. 创建一个新的线程是更好的时候UI更新很少(相对工作完成)

注意。顺便说一下,在10000个循环中,我认为最好显示每千个进度

佴阳曦
2023-03-14

这是因为在循环内计算时阻塞了UI线程。这样的事情应该用回调方法在不同的线程中进行。

作为一种解决方法,您可以导入系统。窗户。形式。dll汇编并调用系统。窗户。形式。应用DoEvents()

    for (int i = 1; i <= 9999; i++)
    {
        System.Windows.Forms.Application.DoEvents();
        // do something
        label1.Content = 100 * i / 9999 + "%";
        Thread.Sleep(10);
    }

但这是一个糟糕的做法!

程枫
2023-03-14

不能在同一线程上同时运行循环和更新UI。这就是为什么您应该始终在后台线程上执行任何长时间运行的工作,并使用dispatcher定期更新UI。

在后台线程上运行某些代码的最简单方法是使用任务并行库(TPL)启动新任务:

Task.Run(()=> 
        {
            for (int i = 1; i <= 9999; i++)
            {
                System.Threading.Thread.Sleep(1500); //simulate long-running operation by sleeping for 1.5s seconds... 
                label1.Dispatcher.BeginInvoke(new Action(() => label1.Content = 100 * i / 9999 + "%"));
            }
        });

我的消息框在百分比运行时运行命令后立即显示消息

如前所述,任务正在另一个线程上执行。所以它将与UI线程并行运行。这就是为什么UI可以在循环运行时更新的原因。

你可以用这个任务。使用方法在任务完成后继续显示MessageBox:

int i = 1;
Task.Run(() =>
            {
                for (; i <= 9999; i++)
                {
                    System.Threading.Thread.Sleep(1500); //simulate long-running operation by sleeping for 1.5s seconds... 
                    label1.Dispatcher.BeginInvoke(new Action(() => label1.Content = (i / 9999) * 100 + "%"));
                }
            }).ContinueWith(t =>
            {
              MessageBox.Show("done..." + i.ToString());
            }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
 类似资料:
  • 问题内容: 我希望在我的网站上有一个百分比圆圈指示器 在这种情况下,显示为75%。应该怎么做?我在图像文件中有一个黄色圆圈,但是如果更容易使用CSS来完成所有操作,那么我可以。 问题答案: 考虑到进度条的形状(结束/开始是四舍五入的),我建议使用SVG。 演示:径向进度栏 径向进度栏 在以下示例中,使用stroke-dasarray属性为进度设置动画效果,并使用jQuery将%数字递增: 不幸的是

  • 下面是我的父组件,它包含一个循环的多个输入。如何选择一个来聚焦?在这种情况下,我必须创建动态吗?

  • 这里是一个以圆圈为单位的交叉网格,当前为5x5。我试图得到一行5,下面是一行4,然后是3,然后是2等等。我试着改变for循环和值,但什么都不起作用。我需要使用行和列吗? 谢谢!

  • 我首先想到的是,一个property_a不能绑定到另一个property_b,这个property_b绑定到property_a或者依赖于属性,这些属性绑定到property_a。对吧?

  • 问题内容: 我正在尝试为xlib窗口创建游戏循环,但是无法正确绘制该窗口。现在,我正在使用XCreateSimpleWindow(…)创建一个窗口,并使用for循环一次绘制所有像素。(这些像素的颜色是从一个大的整数数组中读取的,现在,我将所有像素设置为蓝色。)现在,实际的游戏循环如下: 全局定义了变量dsp,win,pixels,gc。 现在,当我编译并执行二进制文件时,y坐标低的行主要是蓝色,而

  • 问题内容: 我有一个数组(称为),其中包含数百个天文学图像文件的名称。然后处理这些图像。我的代码有效,并且需要几秒钟来处理每个图像。但是,一次只能执行一张图像,因为我是通过循环运行阵列: 没有理由我必须先修改映像,因此可以利用计算机上的所有4个内核,每个内核都通过for循环在不同的映像上运行吗? 我已经阅读了有关该模块的信息,但是不确定如何在我的情况下实现它。我热衷于工作,因为最终我必须在10,0