0

The below code works fine, does not lock the UI, but removing thread.sleep does. Just trying to understand why. Thanks

    public partial class MainFrm : Form
{
     public readonly SynchronizationContext UiContext = null;
     public MainFrm()
        {
        InitializeComponent();
        UiContext = SynchronizationContext.Current;
        }

    private async void Start_Click(object sender, EventArgs e)
    {
    
       await Task.Run(() =>
       {
               for (var i = 0; i <= 5000000; i++)
               {

                   Thread.Sleep(1); //anything but 0 works, having no sleep also fails, why?
                   UiContext.Post(o => { UItextBox.Text = $@"The integer is: {(int) o}"; }, i);
               }
       });
       
    }
}
TD_Home
  • 13
  • 1
  • 4
  • 4
    You are looping 5 million times and calling code that will call back into the UI. That's going to keep the UI very busy unless you allow the UI to take the occasional short breath. Calling `Thread.Sleep(0)` is a special case. It gives up the current thread, but, if nothing grabs control, it just motors along. In all likelihood, using `Thread.Sleep(0)` (if you use it) is essentially a `noop` in your code. Remember, the UI thread operates off a queue of Windows messages. You are filling that queue up licketty-split, not allowing any other UI messages a chance to get in the queue. – Flydog57 Apr 06 '21 at 23:31
  • 1
    You're flooding the UI with messages. Try `Thread.Sleep(100);` to give the UI time to breath. – mr.coffee Apr 06 '21 at 23:44
  • Thanks for the quick responses! I obviously wouldn't do this normally but was just curious why. In particular, why a single millisecond as per my example is all it takes to work without a problem. – TD_Home Apr 06 '21 at 23:58
  • 2
    Think about it. You click a button, you start a thread and it immediately (before much more than a dozen mouse move messages (maybe)) throws 5 million messages in the thread queue, each of which takes some time to process. The UI will then start processing those messages one by one. Any other UI messages will be behind those 5 million. By taking a millisecond breather, you are letting the UI thread do something. It gets to put messages in the queue _between_ the some of the 5 million messages. Your UI was probably sluggish. Sleeping for longer would remove the sluggishness – Flydog57 Apr 07 '21 at 00:30
  • 1
    _"why a single millisecond as per my example is all it takes to work without a problem"_ -- because it's not really just a single millisecond. The time you give `Thread.Sleep()` is the _minimum_ time to sleep. Your thread will be placed in the non-runnable state and other threads will get to run. Using 0, if there are no runnable threads, no yielding happens. Using any positive number, your thread is _forced_ to yield, and that is enough to allow WM_PAINT to happen. See duplicates. – Peter Duniho Apr 07 '21 at 00:59

0 Answers0