0

Why does it block? I know a solution with Dispatcher.PushFrame() but still. Is it the issue of a classic "Don't Block on Async Code" type?

class Program
{
    static void Main(string[] args)
    {
        Test().Wait();
    }

    static async Task Test()
    {
        var disp = Dispatcher.CurrentDispatcher;
        var t = Task.Run(() =>
        {
            disp.Invoke(() =>
            {
                Console.WriteLine("works");
            });
        });
        await t.ConfigureAwait(false);
    }
}

UPD: Now it waits synchronously on the main thread, and uses threadpool dispatcher and still blocks.

    static void Main(string[] args)
    {
        Task.Run(async() => await Test()).Wait();
    }

    static async Task Test()
    {
        var disp = Dispatcher.CurrentDispatcher;
        var t = Task.Run(() =>
        {
            disp.Invoke(() =>
            {
                Console.WriteLine("works");
            });
        });
        await t.ConfigureAwait(false);
    }
  • https://stackoverflow.com/questions/13140523/await-vs-task-wait-deadlock – Legends Sep 22 '17 at 09:56
  • 2
    ` Test().Wait();` is blocking not `await` – Mrinal Kamboj Sep 22 '17 at 09:57
  • since `Wait()` does not wait a task that run on background thread, so when `await ` happend, Main thread is blocked , and so every thead is blocked – John Sep 22 '17 at 10:00
  • Ok, i can rearange example a little, now i'm waiting sychronously on the main thread, while using dispatcher from the threadpool: static void Main(string[] args) { Task.Run(async() => await Test()).Wait(); } static async Task Test() { var disp = Dispatcher.CurrentDispatcher; var t = Task.Run(() => { disp.Invoke(() => { Console.WriteLine("works"); }); }); await t.ConfigureAwait(false); } – Igor Gnilitsky Sep 22 '17 at 10:00
  • I think there is the same issue with main thead, when u `await` , the `Dispatcher` thead is blocked! you should put it inside Task.Run – John Sep 22 '17 at 10:19
  • @John please see update, i'm running it in Task.Run and still blocks. – Igor Gnilitsky Sep 22 '17 at 10:23
  • @IgorGnilitsky It's not in the `t` task, and when u await `t` , current thead blocked (I mean `test` task's thread) – John Sep 22 '17 at 10:28
  • @John no i still do not get how await can block the thread. could you provide a code example of what you mean? – Igor Gnilitsky Sep 22 '17 at 10:34
  • https://github.com/aspnet/ServerTests/issues/86#issuecomment-311243139 – John Sep 22 '17 at 10:45
  • 1
    This test code does not have a functional Dispatcher. The Application.Run() call is crucial to allow it to do what it needs to do. Ignoring this need can only produce deadlock. – Hans Passant Sep 22 '17 at 12:40
  • @HansPassant, do you mean in this case dispatcher doesn't even run anything? I actually have a workaround based on Dispatcher.PushFrame fucntion (can't post teh code unfortunatelly) that if called instead of await t.ConfigureAwait(false); works fine. – Igor Gnilitsky Sep 22 '17 at 13:04

1 Answers1

2

I try this code , and it work. The problem is the how Dispatche work, I think it need a thread that is not stopped and not sleeped and not busy for runing other code .

static Dispatcher dispatcher;
static void Main(string[] args)
{
    dispatcher = Dispatcher.CurrentDispatcher;
    Task.Run(async () => await Test());  //.Wait();

    while (true)
    {
        Dispatcher.PushFrame(new DispatcherFrame());
    }
}

static async Task Test()
{
    //var dispatcher = Dispatcher.CurrentDispatcher;
    var t = Task.Run(() =>
    {
        Console.WriteLine(dispatcher.Thread.ThreadState);
        dispatcher.Invoke(() =>
        {
            Console.WriteLine("works");
        });
    });
    await t; ;
}
John
  • 716
  • 1
  • 7
  • 24
  • Yes, thanks that will work, we have a solution based on PushFrame. Just wanted to know why await doesn't work. – Igor Gnilitsky Sep 27 '17 at 08:08
  • `await` doesn't work because when u `await`, the current thread that is running need to "pause" and release this thread to threadpool (not happend in every time, only happend when it switch thread, and it does for this case : `Task.Run`), that cause dispatcher can not run, and because that the await method will never finish . – John Sep 28 '17 at 06:09