【问题标题】:variable not updating while main thread in while loop在while循环中主线程时变量不更新
【发布时间】:2021-05-27 04:54:08
【问题描述】:

我无法理解线程以及它们如何与程序交互,我只是想创建一个不会停止整个 gui 的延迟,但是在摸索 2019 年 vs 社区时,我发现了一些我无法理解的东西/谷歌。为什么我的主线程在 while 循环中时我的变量“stickler”没有更新? 我使用断点来确定线程没有更新变量。没有断点它也不起作用。

    using System;
using System.Threading;
using System.Windows.Forms;

namespace dang_2_22_21
{
    public partial class C5E9 : Form
    {
        public C5E9()
        {
            InitializeComponent();
        }

        private void C5E9_Load(object sender, EventArgs e)
        {
            
        }


        static volatile int stickler;
        public void AAAAAA()
        {
            stickler++;
            textBox1.Invoke((Action)delegate
           {
               textBox1.Text = stickler.ToString() + "ms(not)";
           });
        }

        private void Timer1_Tick(object sender, EventArgs e)
        {

        }
        public void sleeper(int time)
        {
            time = time + stickler;
            while (time > stickler)
            {
                //hehehehehheehheheheeheheheehheheheheehehehhehehehhehehehehehehheehehheheeeheheheheheheeeeehehhhhheheheheeeehehehehehhehehhehehehehhehehhehehheehehhehehehehehehhe
                //i hope this work.
                //it doont.
                //timer is on the same thread, whY?
            }
        }
        private void NumericUpDown2_ValueChanged(object sender, EventArgs e)
        {
            decimal result;
            decimal start;
            start = numericUpDown2.Value;
            result = start;

            while (true)
            {
                start--;
                if (start == 0)
                {
                    break;
                }
                result = result * start;
                sleeper(100);
                numericUpDown3.Value = result;
            }
        }

        private void TextBox1_TextChanged(object sender, EventArgs e)
        {
            Thread t = new Thread(new ThreadStart(AAAAAA));
            t.Start();
        }
    }
}

【问题讨论】:

  • 不是你的反对者,而是我们在看哪个代码?这听起来像 TextBox,但你也有 NumericUpDown。
  • 好的,所以有一个线程来处理更新 UI,它被称为 UI 线程。任何被调用的事件处理程序都是在 UI 线程上完成的,因此通过在该线程中循环,您将阻止 UI 更新。正如有人回答的那样,使用 aync 是因为正确处理这些东西并不简单,并且 async 使线程更容易。您也可以使用后台任务,但异步是 现代 等价物。
  • 请注意,volatile 可能不会像您认为的那样做,它只是一个半屏障。对于完整的内存屏障和缓存行跳过,请使用Interlocked.Read

标签: c# multithreading winforms


【解决方案1】:

要在不阻塞 UI 的情况下“休眠”,请使用异步方法。

private async void NumericUpDown2_ValueChanged(object sender, EventArgs e)
{
    var start = numericUpDown2.Value;
    var result = start;

    while (start > 0)
    {
        start--;
        
        result = result * start;
        await Task.Delay(100); // "sleeping" for 100 milliseconds
        numericUpDown3.Value = result;
    }
}

【讨论】:

  • 非常感谢!这可能比线程容易得多!
猜你喜欢
  • 2019-03-05
  • 1970-01-01
  • 1970-01-01
  • 2019-03-11
  • 2016-01-25
  • 2014-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多