0

I'm new to asynchronous programming, I always have difficulty in understanding UI thread lifecycle. Let's said we work on a webform, and in the page load method, we made an asynchronous call as:

private SynchronizationContext uiCtx;
...
protected void Page_Load(object sender, EventArgs e)
{
   if (!this.IsPostBack)  
   {
       ... 
       WebRequest req = WebRequest.Create("http://www.google.com/#q=weather");
       // Must make this call on the UI thread
       uiCtx = SynchronizationContext.Current;

      AsyncCallback callback = delegate(IAsyncResult iar)
                              {
                                 WebResponse resp = req.EndGetResponse(iar);
                                 ProcessResponse(resp);
                              };
      req.BeginGetResponse(callback, null);
      ...
   }
}

private void ProcessResponse(WebResponse resp)
{
    // This code is on the threadpool thread
    StreamReader reader = new StreamReader(resp.GetResponseStream());
    SendOrPostCallback callback = delegate
    {
       // this runs on the UI thread
       UpdateUI(reader.ReadToEnd());
      // must Dispose reader here as this code runs async
      reader.Dispose();
    };
    uiCtx.Post(callback, null);
}

I can get the idea that we want a work thread to get the job done and update UI, so we use SynchronizationContext to move work back onto the UI thread.

I have the following questions:

Q1-Why the worker thread is not supposed to update UI directly, is any particular reasons for that?

Q2-We know that for asynchronous programming model, the worker threads in the thread pool are background threads. Let's assume the async call takes 3 seconds to get the result back, but the main thread will finish quickly after the page_load, if UI thread has already finished, it cannot execute the job passed from the worker thread, can it? So how can we control the UI thread to let it not finishing quickly?

Q3-if the worker thread finishes first, now the job will be moved back to UI thread, let's suppose that UI thread is also executing something else, so does it mean that the UI thread will get its job done first then start to execute the work passed from the worker thread?

Peter Duniho
  • 68,759
  • 7
  • 102
  • 136
  • See second-highest-voted answer on first duplicate for discussion of affinity for Winforms. The WPF discussion is also pertinent, simply because this concept of thread affinity for UI objects exists in all mainstream GUI APIs, whether Java, Mac OS, Android, native Win32, etc. That addresses your first question. Asking multiple disparate questions makes your question also "too broad". Try narrowing the topic and posting as individual questions. Make sure you do research, and explain what you have already found, for each specific question. – Peter Duniho Sep 16 '19 at 00:12
  • 1
    I will note that your question expresses some misconceptions: for I/O there's generally not a thread involved at all, until the I/O actually completes; for the UI thread, that thread _never_ completes...it's always running, always looking in its message queue for more things to do. Your third question is easy: a single thread can only ever do one thing at a time, so of course, yes the UI thread must finish whatever it's currently doing before it can service the invoked work passed to it by the worker thread. – Peter Duniho Sep 16 '19 at 00:14
  • @PeterDuniho I never thought UI thread never finishes, I have a big misunderstanding in that. So just to confirm again, for aspx page, the first time it execute, the main thread/UI thread never completes, if I click a dropdown box to trigger a post back, it will be the same main thread that will handle the request? –  Sep 16 '19 at 00:39
  • ASP.NET is a whole 'nother ball o' wax, but with very similar requirements. There's no UI thread per se (since the actual UI is on the client side), and requests often are served on a thread pool basis. But, ASP.NET still has synchronization context, objects with affinity, and a requirement (for slightly different but not entirely unrelated reasons) that those objects are accessed in the correct synchronization context. – Peter Duniho Sep 16 '19 at 00:42

0 Answers0