C# Winforms: A thread that can control the UI and can “sleep” without pausing the whole program. How?

前端 未结 4 1843
-上瘾入骨i
-上瘾入骨i 2021-01-14 05:31

OK...

Looks like WinForms and Threading in the same program is something that I can\'t master easily.

I\'m trying to make a custom Numeric Up Down out of two

相关标签:
4条回答
  • 2021-01-14 06:02

    If you are willing to download the Async CTP (or wait for C# 5.0) you can use the new async and await keywords to make for a really elegant solution.1

    public class YourForm : Form
    {
      private async void UpPictureBox_Click(object sender, EventArgs args)
      {
        await Task.Delay(500);
        timer1.Enabled = is_mouse_down;
      }
    
      private async void DownPictureBox_Click(object sender, EventArgs args)
      {
        await Task.Delay(500);
        timer1.Enabled = is_mouse_down;
      }
    }
    

    The await keyword in the code above will yield control back to the message loop while the delay task is executing. Execution will pick back up where it left off upon completion of that task. This is but one among many reasons why the new keywords are so wicked cool.


    1Note that the Async CTP uses TaskEx instead of Task.

    0 讨论(0)
  • 2021-01-14 06:05

    To answer your actual question, use this:

    private void declare_thread()
    {
        //some work
        Thread delay = new Thread(new ThreadStart(delay0));
        delay.Start();
        //some more work
    }
    
    //other functions
    private void delay0()
    {
        //delay_for_500ms.WaitOne();
        Thread.Sleep(500);
        this.Invoke((ThreadStart)delegate()
        {
    
        if (is_mouse_down)
        timer1.Enabled = true;
        });
    }
    

    Of course your whole mental model of proper, event driver programming is wrong. You'd fit in better with the old single-task DOS people 20 years ago.

    If you want to wait half a second before doing something, set a timer for 500ms and exit your function. Let the timer tell you when it's done so you can do the second half:

    // on the main thread
    
    // la la la doing work
    // wait 500ms
    var tmr=new Timer{Interval=500};
    tmr.Tick+=(s,e)=>{/*action .5sec later*/ btn.Enabled=false; tmr.Enabled=false;};
    tmr.Enabled=true;
    
    // and quit
    return;
    
    0 讨论(0)
  • 2021-01-14 06:07
    button.Click += delegate { BeginInvoke(new UiUpdate(delegate { Thread.Sleep(500); // Do Stuff After Sleep };)) };
    
    private delegate void UiUpdate();
    
    0 讨论(0)
  • 2021-01-14 06:20

    You're looking for the wrong answer to the problem. There's no such thing as a thread which can access UI controls and sleep without blocking the UI. Only the UI thread can access UI controls safely, and if you make the UI thread sleep, your UI will be unresponsive.

    I'm afraid you need to bite the bullet and learn how to perform the threading properly. Note that sleeping is almost always the wrong approach - especially in the UI thread. You ahven't really said what you're trying to do, but a timer is a good way of saying, "I want to perform some action at a later point in time." There are various different timers in .NET - which one you should use will depend on what you're trying to do.

    Threading is one of those topics that you can't really shortcut - you should consider reading a thorough tutorial or a book which covers it in detail.

    0 讨论(0)
提交回复
热议问题