代码之家  ›  专栏  ›  技术社区  ›  Lennart

没有wait的Dispatcher.BeginInvoke()是否仍异步执行?

  •  0
  • Lennart  · 技术社区  · 7 年前

    我很难理解dispatcher的异步方法和async/await之间的联系。

    在我的例子中,我有一个事件处理程序,它在dispatcher上执行一个操作:

     private void OnEventOccurred(object sender, EventArgs e)
     {
         someControl.Dispatcher.BeginInvoke(DispatcherPriority.Background, SomeLongRunningOperation());
     }
    

    这应该不会阻塞UI线程,对吗?至少在我们的应用程序中感觉是这样。与async/await版本有什么区别?

     private async void OnEventOccurred(object sender, EventArgs e)
     {
         await someControl.Dispatcher.BeginInvoke(DispatcherPriority.Background, SomeLongRunningOperation());
     }
    

    这同样有效,而且在UI响应性方面似乎没有什么不同。

    3 回复  |  直到 7 年前
        1
  •  1
  •   mm8    7 年前

    这应该不会阻塞UI线程,对吗?

    SomeLongRunningOperation() BeginInvoke 方法是事件处理程序将恢复一次 SomeLongRunningOperation() 已在UI线程上完成执行。所以如果你打电话后什么都不做 ,使用 await 关键字在这里。

    当您执行以下操作时 MessageBox 将显示在 SomeLongRunningOperation

    private void OnEventOccurred(object sender, EventArgs e)
    {
        Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(SomeLongRunningOperation));
        MessageBox.Show("SomeLongRunningOperation will be executed eventually!");
    }
    

    当您执行以下操作时,它将在 一些长期运行的操作

    private async void OnEventOccurred(object sender, EventArgs e)
    {
        await Dispatcher.BeginInvoke(DispatcherPriority.Background, new Action(SomeLongRunningOperation));
        MessageBox.Show("SomeLongRunningOperation has been executed!");
    }
    

    所以等着你的电话是没有意义的 异步调用 如果在方法返回后不想在事件处理程序中添加任何内容。

    一些长期运行的操作 是一个可能长时间运行的操作,您应该在后台线程上执行它。最简单的方法就是开始一个 Task ,您可以等待:

    await Task.Run(SomeLongRunningOperation);
    
        2
  •  1
  •   LadderLogic    7 年前

    BeginInvoke Dispatcher (UI线程)来执行此操作,在您的情况下是长时间运行的,而不阻塞调用线程。如果你决定使用 Invoke 相反,调用线程被阻塞,直到 调度员 已完成执行您提供的委托。

    异步调用 并不意味着工作是在不同的线程上异步完成的。您要做的是在另一个任务上启动这个SomeLongRunningOperation,并使用异步等待模式返回它,就像您在第二个示例中尝试的那样。像这样:

     private async void OnEventOccurred(object sender, EventArgs e)
     {
         await Task.Run(SomeLongRunningOperation());
     }
    
        3
  •  0
  •   Sham    7 年前

    所有代码分配给 Dispatcher TPL 用于长时间运行的任务和 调度员