2017-09-22 72 views
0

它为什么会阻止?我知道Dispatcher.PushFrame()的解决方案,但仍然如此。这是一个经典的“不要阻止异步代码”类型的问题吗?为什么等待块Dispatcher.Invoke?

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:现在它在主线程上同步等待,并使用线程池调度程序并仍然阻塞。

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); 
    } 
+0

https://stackoverflow.com/questions/13140523/await-vs-task-wait-deadlock – Legends

+2

'测试()等待();'阻止不'await' –

+0

因为'等待()'不会等待在后台线程上运行的任务,所以当'waiting'发生时,主线程被阻塞,所以每个阻塞都被阻塞 – John

回答

2

我试试这个代码,它的工作。问题是如何Dispatche的工作,我认为它需要一个线程,不停止,不睡觉,不忙于运行其他代码。

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; ; 
} 
+0

是的,谢谢,这将工作,我们有一个基于PushFrame的解决方案。只是想知道为什么等待不起作用。 –

+0

'await'不起作用,因为当你等待时,正在运行的当前线程需要“暂停”并将此线程释放到线程池(每次都不会发生,只有在切换线程时才会发生)这种情况:'Task.Run'),导致调度程序无法运行,并且因为await方法永远不会结束。 – John