-1

Why does a function not run procedurally? I would expect the following code would first show a TextBox, then idle for 3 seconds, and hide the TextBox, but the application simply sleep for 3 seconds without showing the TextBox

public Main()
{
   MyTextBox.Visibility = Visibility.Visible;
   Thread.Sleep(3000);
   MyTextBox.Visibility = Visibility.Hidden;
}



[EDIT 1]
I can't really find an explanation as to why the thread did not sleep AFTER the textbox goes visible. Thread.Sleep should not start until the previous line MyTextBox.Visibility finished running. Hence, my question: why aren't the statement not run procedurally/sequentially?


[EDIT 2]
I can understand the downvotes but yet I could not find an explanation from "duplicate" questions. The UI thread should render my TextBox.Visibility before Thread.Sleep(3000), but that's not the case.

My original thought of how the UI thread should go:

Main() -> Initialize UI Controls -> Run Constructor -> Set TextBox.Visibilily Property (Visible) -> Render TextBox visible on GUI -> Thread.Sleep(3000) -> Set TextBox.Visibility Property (hidden) -> Render TextBox hidden on GUI

But in practice, the thread looks more like the following:

Main() -> Initialize UI Control -> Run Constructor -> Set TextBox.Visibilily Property (Visible) -> Set TextBox.Visibilily Property (Hidden) -> Thread.Sleep(3000) -> Render TextBox visible on GUI -> render TextBox hidden on GUI

KMC
  • 19,548
  • 58
  • 164
  • 253
  • 1
    Because Thread.Sleep inevitably blocks the UI thread. This has been asked and answered too many times here. – Clemens Jul 14 '17 at 10:56
  • Because the `Thread.Sleep` makes the GUI-thread sleep for 3 seconds so your app freezes – Tim Schmelter Jul 14 '17 at 10:56
  • @KMC you should user timer tick – Roxy'Pro Jul 14 '17 at 10:57
  • But it should show my textbox before freezing my app – KMC Jul 14 '17 at 10:58
  • That would require the method to return after you have set the property to Visibility.Visible but before calling Thread.Sleep. It doesn't. – mm8 Jul 14 '17 at 10:59
  • @mm8: while that might be true it's not the way you'd exprect because all statements of a method are processed sequentially – Tim Schmelter Jul 14 '17 at 11:04
  • @Tim Schmelter: That's my point. The method is processed sequentially and blocks the UI thread. – mm8 Jul 14 '17 at 11:08
  • @mm8: then it lacks an explanation. @KMC: is the textbox visible if you call `this.Refresh();` before the Thread.Sleep? – Tim Schmelter Jul 14 '17 at 11:09
  • @mm8: but there is no this.Refresh() available. My question is why the textbox did not go visible before thread goes to sleep. – KMC Jul 14 '17 at 11:27
  • @mm8: Refresh() is WinForm, not WPF – KMC Jul 14 '17 at 11:31
  • I haven't mentioned any Refresh method...@Tim Schmelter has. What's your point? I have already answered your question, haven't I? – mm8 Jul 14 '17 at 11:47
  • Setting the Visibility property doesn't force the UI to re-render immediately. That's not how WPF works. – mm8 Jul 14 '17 at 11:49

1 Answers1

2

It does indeed run synchronously on the same thread but the UI thread cannot both sleep and hide/show the TextBox simultaneously.

A single thread cannot do two things simultaneously.

mm8
  • 163,881
  • 10
  • 57
  • 88
  • 2
    I think he wonders why `MyTextBox.Visibility = Visibility.Visible;` doesn't show the textbox and refreshes the gui in this line. I think this question addresses this topic: https://stackoverflow.com/questions/2341731/why-wont-control-update-refresh-mid-process – Tim Schmelter Jul 14 '17 at 11:01
  • Setting a property doesn't cause the UI to be re-rendered immediately. – mm8 Jul 14 '17 at 12:55
  • I'm not asking the UI thread to do two things simultaneously - the UI thread should first set the visibility properties before sleeping the thread. Or is it because the UI graphic gets rendered/refreshed only when the UI thread is idle or done processing the logic? If that's the case, the UI thread has two part: first it process the logic then render graphics at last? – KMC Jul 15 '17 at 06:19
  • The rendering takes place on a dedicated rendering thread. There is no immediate rendering mode in WPF. So, as mentioned, setting the Visibility doesn't cause the UI to get re-rendered immediately. It will get rendered eventually but not before you go to sleep and block. – mm8 Jul 17 '17 at 07:25
  • I thought the rendering is part of the UI thread, so the UI thread does not handle rendering. Can I access the render thread and force it to update? – KMC Jul 31 '17 at 08:48