在执行异步操作时显示模态对话框

Show modal dialog while performing an asynchronous operation

我目前正在尝试在执行异步操作时显示对话框。

我的架构之前是基于事件的,因为我希望用户可以轻松实现自定义图形用户界面。

现在我正在转向其他方式,在我的例子中,return 类型用于同步方法,而不是包含数据的 EventArgs,然后是异步等待 + 任务。

示例:

public bool SearchForUpdates()
{
   // ...
   return true;
}

现在我的异步方法应该是这样的:

public async Task<bool> SearchForUpdatesAsync()
{
    return await Task.Factory.StartNew(() => SearchForUpdates());
}

这些方法定义在Manager-class中。 第一:异步方法等待同步方法是正确的还是同步方法应该等待异步方法?

然后还有一个class是Manager-class和UI之间的接口。 搜索更新时,应显示相关对话框:

public async void ShowUserInterface()
{
    var searchDialog = new SearchDialog();
    Task<bool> searchTask = _manager.SearchForUpdatesAsync();
    IAsyncResult result = searchDialog.BeginInvoke(new Action(() => seachDialog.ShowDialog()));
    bool updatesFound = await searchTask;

    if (((DialogResult)searchDialog.EndInvoke(result)) == DialogResult.Cancel)
    {
        // Cancelled, do stuff 
    }
    searchDialog.Close();
}

这就是我的想法,所以会有一种方法可以调用它并显示自定义 UI。 逻辑问题:Invoke 或 BeginInvoke 在创建 window 句柄之前无法在控件上调用。

我的计划好像失败了,是不是完全错了?或者有没有办法显示这样的对话框?应该有一种方法可以使 ShowDialog 成为非阻塞的,这样我就可以继续等待调用。所以我实际上正在寻找一种调用 BeginInvoke 的方法,但我不知道在哪里,WPF 中的 Application.Current.Dispatcher.Invoke 可能,我不知道。

谢谢!

如评论中所述,您只是使用了错误的控件引用来调用 BeginInvoke()。该对话框无法工作,尚未创建。这一点很重要,在 window 提交给特定线程之前,.NET 无法确定哪个线程拥有 window。在您调用 Show() 之前不会发生这种情况。

但任何其他 window 都可以,您必须已经有一个,因为在没有所有者的情况下显示对话框是不合法或不切实际的。您必须提供构造函数或 属性,以便客户端代码可以提供对此类 window 的引用。任何一个都可以,应用程序的主要 window 是一个实用的选择。

您可以通过在构造函数中复制 Synchronization.Current 的值,将 class 与 UI 实现完全分开(此处不实用,因为您显示了一个对话框)。您稍后可以在其上调用其 Post() 方法。 .NET 中的所有 UI class 库都安装了一个同步提供程序来编组调用。