Task.Factory.StartNew and sync context

Simple question. Here is part of the WinForms application:

void Form1_Load(object sender, EventArgs e)
{
    var task2 = Task.Factory.StartNew(() => MessageBox.Show("Task!"),
        CancellationToken.None,
        TaskCreationOptions.None,
        TaskScheduler.FromCurrentSynchronizationContext());

    Debug.WriteLine("Before Exit");
    MessageBox.Show("Exit!");
}

Can someone explain why I see "Task!". first and then "Exit" when I run this?

And when I see "Task!" the "Before Exit" message box has already been printed at the debug output.

EDIT: simpler, same effect:

void Form1_Load(object sender, EventArgs e)
{
    SynchronizationContext.Current.Post((_) => 
        MessageBox.Show("Task!"), null);

    Debug.WriteLine("Before Exit");
    MessageBox.Show("Exit!");
}

EDIT: if I replace MessageBox.Show("Exit!")with Form { Text = "Exit!" }.ShowDialog(), I see "Exit" and then "Task", as expected. Why is this?

+3
source share
3 answers

Exact information about forwarding Win32 messages in the .NET Framework is undocumented. Note that the Win32 API has historically allowed repeated behavior.

, , , SynchronizationContext. , SynchronizationContext.Current.Post, .

WindowsFormsSynchronizationContext , Win32 ; .NET, " ". ( ).

MessageBox.Show, , . Exit!, , Form1_Load Application.Run.

+3

, :

  • . , () , " , ".
  • MessageBox.Show. , () .
  • SendMessage , . , , .

, , , . Debug.WriteLine Thread.Sleep, , , : ( ), Task.

: OP ShowMessage, new Form. , , , SendMessage , . (, , , SendMessages , , - , , .)

, - - MessageBox.Show , , , new Form().ShowDialog() - wasn ' t . - , .

+4

, .

  • MessageBox.Show . ThreadContext, , , , - , . Show , , .
  • MessageBox Form - user32.dll , .
  • ThreadPool.QueueUserWorkItem. , ( -). , , , .NET. : . , , WindowsFormsSynchronizationContext, , Windows.
  • , .
  • . MessageBox.Show .

await (await Task.Delay(1000);), - "!" ., "!" . ?! ?!

, "!" "!". , . , - " " .

, . , , . await, "!". , () .

Thread.Sleep(1000); await, . , Thread.Sleep "!". , , "!" , "!" , , "!" .

Windows. "" . , , WM ( "set focus" ).

await , . , , , , - MessageBox ( .NET Form!), - , "!" . .

, , - , - MessageBox.Show("Exit!");, .

:

. , , - , . , , .

, ""! , - "!" , - ( ), ""! .

, MessageBox.Show("Exit!"); ( Application.EnterThreadModal). WinAPI (user32.dll) MessageBox, . WM, Invoke - "!" . . Message.Show, .

, . -, MessageBox.Show, , .

In fact, you would run your task outside of the user interface thread, and only a continuation requiring access to the user interface would be in the user interface thread. However, it is very interesting how it MessageBoxcaptures what is happening - it can have unpleasant consequences if your background task gets stuck, causing something in the user interface thread, which is effectively transmitted in the message window; your asynchrony goes there :))

0
source

All Articles