【问题标题】:C# winform blink label backcolor with delayC# winform 带有延迟的闪烁标签背景色
【发布时间】:2015-01-08 18:50:41
【问题描述】:

我有一个 winform 应用程序,我需要让标签背景色闪烁。我正在尝试使用 for 循环和 Thread.Sleep 来做到这一点,但不起作用。感谢您的帮助和建议:

private void button1_Click(object sender, EventArgs e)
{
    for (int i = 0; i < 10; i++)
    {
        System.Threading.Thread.Sleep(1000); // Set fast to slow.
        if (label1.BackColor == Color.Red)
            label1.BackColor = Color.Transparent;
        else
            label1.BackColor = Color.Red;
    }
}   

【问题讨论】:

    标签: c# windows multithreading timer task


    【解决方案1】:

    使用 UI 计时器,而不是为此任务休眠。您一直在使主线程处于睡眠状态,并且正在阻止用户输入。使用Thread.Sleep几乎总是表明你做错了什么。 Thread.Sleep 正确的情况很少。具体来说,将 UI 线程置于睡眠状态是从不正确的。

    Timer 组件放在您的表单和Tick 事件中,不断更改标签的背景颜色。

    例如:

    // Keeps track of the number of blinks
    private int m_nBlinkCount = 0;
    
    // ...
    
    // tmrTimer is a component added to the form.
    tmrTimer.Tick += new EventHandler(OnTimerTick);
    
    m_nBlinkCount = 0;
    tmrTimer.Interval = 1000; // 1 second interval
    tmrTimer.Start();
    
    // ...
    
    private void OnTimerTick ( Object sender, EventArgs eventargs)
    {
        if (label1.BackColor == Color.Red)
            label1.BackColor = Color.Transparent;
        else
            label1.BackColor = Color.Red;
    
        m_nBlinkCount++;
    
        if ( m_nBlinkCount >= 10 )
            tmrTimer.Stop ();
    }
    

    【讨论】:

      【解决方案2】:

      这里发生的情况是您正在休眠 GUI 线程,这会导致程序挂起。 GUI 线程也是负责更改标签背景颜色的线程。

      这里有一个简单的实现可以为您解决这个问题。请注意,这可能不是最好的实现,但它使用您首选的闪烁代码实现。要获得比 Thread.Sleep 更好的选择,请参阅 System.Timers.Timer 或 xxbbcc 建议的 System.Windows.Forms.Timer。

          BackgroundWorker blinker;
      
          public Form1()
          {
              InitializeComponent();
              blinker = new BackgroundWorker();
              blinker.DoWork += blinker_DoWork;
          }
      
          private void blinker_DoWork(object sender, DoWorkEventArgs e)
          {
              for (int i = 0; i < 10; i++)
              {
                  System.Threading.Thread.Sleep(1000); // Set fast to slow.
      
                  if (label1.InvokeRequired)
                  {
                      label1.Invoke((Action)blink);
                  }
                  else
                  {
                      blink();
                  }
              }
          }
      
          private void blink()
          {
              if (label1.BackColor == Color.Red)
                  label1.BackColor = Color.Transparent;
              else
                  label1.BackColor = Color.Red;
          }
      
          private void button1_Click(object sender, EventArgs e)
          {
              if (blinker.IsBusy == false)
              {
                  blinker.RunWorkerAsync();
              }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-17
        • 1970-01-01
        相关资源
        最近更新 更多