I'm trying to asynchronously show a progress form that says the application is running while the actual application is running.
As following this question, I have the following:
Main Form:
public partial class MainForm : Form
{
    public MainForm()
    {
        InitializeComponent();
    }
    async Task<int> LoadDataAsync()
    {
        await Task.Delay(2000);
        return 42;
    }
    private async void Run_Click(object sender, EventArgs e)
    {
        var runningForm = new RunningForm();
        runningForm.ShowRunning();
        var progressFormTask = runningForm.ShowDialogAsync();
        var data = await LoadDataAsync();
        runningForm.Close();
        await progressFormTask;
        MessageBox.Show(data.ToString());
    }
}
Progress Form
public partial class RunningForm : Form
{
    private readonly SynchronizationContext synchronizationContext;
    public RunningForm()
    {
        InitializeComponent();
        synchronizationContext = SynchronizationContext.Current;
    }
    public async void ShowRunning()
    {
        this.RunningLabel.Text = "Running";
        int dots = 0;
        await Task.Run(() =>
        {
            while (true)
            {
                UpadateUi($"Running{new string('.', dots)}");
                Thread.Sleep(300);
                dots = (dots == 3) ? 0 : dots + 1;
            }
        });
    }
    public void UpadateUi(string text)
    {
        synchronizationContext.Post(
            new SendOrPostCallback(o =>
            {
                this.RunningLabel.Text = text;
            }),
            text);
    }
    public void CloseThread()
    {
        synchronizationContext.Post(
            new SendOrPostCallback(o =>
            {
                this.Close();
            }),
            null);
    }
}
internal static class DialogExt
{
    public static async Task<DialogResult> ShowDialogAsync(this Form form)
    {
        await Task.Yield();
        if (form.IsDisposed)
        {
            return DialogResult.OK;
        }
        return form.ShowDialog();
    }
}
The above works fine, but it doesn't work when I'm calling from outside of another from. This is my console app:
class Program
{
    static void Main(string[] args)
    {
        new Test().Run();
        Console.ReadLine();
    }
}
class Test
{
    private RunningForm runningForm;
    public async void Run()
    {
        var runningForm = new RunningForm();
        runningForm.ShowRunning();
        var progressFormTask = runningForm.ShowDialogAsync();
        var data = await LoadDataAsync();
        runningForm.CloseThread();
        await progressFormTask;
        MessageBox.Show(data.ToString());
    }
    async Task<int> LoadDataAsync()
    {
        await Task.Delay(2000);
        return 42;
    }
}
Watching what happens with the debugger, the process gets to await Task.Yield() and never progresses to return form.ShowDialog() and thus you never see the RunningForm. The process then goes to LoadDataAsync() and hangs forever on await Task.Delay(2000).
Why is this happening? Does it have something to do with how Tasks are prioritized (ie: Task.Yield())?
 
    