循环中的代码仅在循环完成后才能工作

时间:2013-12-02 04:02:10

标签: c#

我有一个名为 ExecuteLoop 的函数为

private void ExecuteLoop()
{ 
 for(int i=0;i<10000;i++)
 lable1.Text=i;
}

但标签文字没有改变。在循环结束时它显示为“10000”

怎么办?

2 个答案:

答案 0 :(得分:2)

我假设你正在使用winforms? winforms控件隐藏了很多关于真实情况的细节。在较低级别,您的程序将依赖于.Net框架中的代码,如下所示:

while (true)
{
    var message = GetMessagesFromOperatingSystem();
    HandleReceivedMessage(message);
    if (message == WM_QUIT) return;
}

这称为消息泵或消息循环。这不是真正的代码,但它应该给你这个想法。

当您更改标签文本或设置控件上的任何其他属性时,该属性的setter会调用一个函数,该函数告诉操作系统为您的控件分配的屏幕空间现在无效,并且需要重新启动画。然后,Windows会将消息发回给您需要重绘该空间的程序。上面演示的代码接收到此消息,并且该代码与for循环位于同一个线程中。所有这些的最终结果是不会对控件属性进行任何更改屏幕上显示,直到方法结束。

有几种方法可以解决这个问题。对你的情况最好的将取决于你真正想做的事情。作为快速示例,如果您尝试显示时钟,则可能需要使用计时器组件,并将代码移至计时器的tick事件,而不是在循环中使用延迟。如果这是稍后将添加的更复杂工作的占位符,您可能想要使用BackgroundWorker组件(尽管它最初会看到过度杀伤的东西如此简单)。

答案 1 :(得分:0)

它没有显示中间值,因为您没有在使用Timer之间添加延迟,以查看Label Text0 to 10000更改。

试试这个:

public partial class Form1 : Form
    {
       int count = 0;
       int maxlimit=10000;
        System.Windows.Forms.Timer timer1 = new System.Windows.Forms.Timer();

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            button1.Enabled = false;
            SetTimer(500);
        }
        private void SetTimer(int milliseconds)
        {            
            timer1.Interval = milliseconds;
            timer1.Tick += new EventHandler(timer1_Tick);
            timer1.Start();
        }
        private void timer1_Tick(Object o, EventArgs e)
        {
            if (count < maxlimit)
            {
                label1.Text = count.ToString();
                count++;
            }
            else
            {
                count = 0;
                button1.Enabled = true;
                label1.Text = "completed!";
                timer1.Stop();

            }
        }