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

时间:2015-03-22 13:50:03

标签: c# winforms asynchronous

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

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

现在我正在寻找其他方法,在我的情况下,返回同步方法的类型,而不是包含数据的EventArgs,然后是async-await + tasks。

示例:

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

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

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

这些方法在Manager类中定义。 第一:async方法是等待同步方法还是同步方法等待异步方法?

然后还有另一个类,它是Manager类和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。

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

谢谢!

1 个答案:

答案 0 :(得分:1)

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

但是任何其他窗口都可以,你必须已经拥有一个窗口,因为显示没有所有者的对话框是不合法或不实际的。您必须提供构造函数或属性,以便客户端代码可以提供对此类窗口的引用。任何人都会这样做,应用程序的主窗口是一个实用的选择。

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