【问题标题】:Task.Run global Messagebox which blocks main windowTask.Run 阻止主窗口的全局消息框
【发布时间】:2019-01-23 15:07:16
【问题描述】:

我在我的 WPF 应用程序的构造函数中运行了一个等待的函数:

  Task.Run(async () =>
  {
      var r = await checkValidLicenseAsync(hardwareid);
      if (r == false)
        MessageBox.Show("no License.");
  }

消息框没有挡住我的主窗口。我想这是因为我在一个任务中运行?什么是解决方法?

【问题讨论】:

  • 在 GUI 线程上调用它。抛出异常,稍后处理并显示消息框。
  • 如何在 GUI 线程上调用?
  • 不要使用任务,使用 ShowDialog 保持焦点
  • 我无法在构造函数中运行异步函数
  • "如何在 GUI 线程上调用?"请谷歌一下,谢谢。

标签: c# wpf


【解决方案1】:

您希望将此代码作为任务运行吗?它在这里没有提供任何优势。已经使用 await 调用了可能长时间运行的许可证验证,使其成为非 UI 阻塞(除非它的实现被搞砸了)。

要使消息框阻塞,即模态,只需编写

  bool valid = await checkValidLicenseAsync(hardwareid); // non-blocking
  if (!valid) {
      MessageBox.Show("no License."); // blocking
  }

假设这是 System.Windows.MessageBox 而不是它的 winforms 挂件。

一种可能的方法是使用工厂方法返回对象。另一种是使用AsyncLazy<T>,如here by Stephen Cleary所述

另请参阅: - Svick's answerCan constructors be async?

【讨论】:

  • 我在构造函数中运行此代码。在构造函数中,我不能等待方法
  • 构造函数应该始终让对象完全初始化。构造函数也不应该失败。
  • 好的,我想我必须将我的代码移动到我的主窗口的加载事件中
【解决方案2】:

我不认为您可以将可等待的方法调用到构造函数中。由于构造函数不能添加异步描述符。您可以在构造函数中调用委托。只需将您的逻辑包装到异步委托中

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 2018-12-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多