6

I am writing a continuous polling loop to watch for some events to happen and then take some action on UI thread.

I am writing following code

public static void HandlePopup(this HostedControl control, string className, string caption, System.Action callback)
    {
        var popupTask = Task.Factory.StartNew(() =>
        {
            Thread.Sleep(5000); // just wait for 5 seconds.
        }, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).ContinueWith((prevTask) =>
        {
            AutomationElementCollection collection = null;
            do
            {

            } while (true);
        }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith((prevTask) =>
        {
            if (!prevTask.IsFaulted)
            {
                if (control.InvokeRequired)
                {
                    control.Invoke(callback);
                }
                else 
                {
                    callback();
                }
            }
        }, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());

        try
        {
            ////popupTask.Wait();
        }
        catch (AggregateException ex)
        {
            ex.Handle(exnew =>
            {
                return true;
            });
        }
    }

The do while loop does not have any code now, because I want to test that if i run a loop infinitely the UI does not block, however , it is not working as expected and when the code runs this loop (which will never return) the UI freezes and becomes unresponsive untill i break the run.

What should i do to make it run silently in the background,

Note : the parent from where this method is called is a Web browser controlsdocumentcompelte` event. The web browser control is inside windows forms application.

John Saunders
  • 160,644
  • 26
  • 247
  • 397
shashank
  • 123
  • 9
  • I have edited your title. Please see, "[Should questions include “tags” in their titles?](http://meta.stackexchange.com/questions/19190/)", where the consensus is "no, they should not". – John Saunders Dec 17 '13 at 08:28

1 Answers1

15

You're explicitly telling the continuation to run in the current synchronization context by specifying

TaskScheduler.FromCurrentSynchronizationContext()

So yes, that will block the UI thread because it's running in the UI thread assuming this overall method is called in a UI thread. The original task will run in the background, but your continuations are both scheduled to run in the UI thread. If you don't want to do that, don't use that task scheduler.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • You know? I been struggling with this code for an hour now only to realize that I was doing such a stupid mistake :). Thanks a ton :) – shashank Dec 17 '13 at 08:27
  • Could you please update with unanswered part of the question: "What should i do to make it run silently in the background?" (To run the continuation task in main/UI thread without blocking the UI while the dependent task runs to completion)? – Sen Jacob Oct 29 '19 at 03:49
  • For future visitors: Maybe trying with a combination of [`async` `await` and `Dispatcher.BeginInvoke()`](https://stackoverflow.com/a/25965053/399414) can help ? – Sen Jacob Oct 29 '19 at 04:24