在执行异步操作时显示模态对话框
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 库都安装了一个同步提供程序来编组调用。
我目前正在尝试在执行异步操作时显示对话框。
我的架构之前是基于事件的,因为我希望用户可以轻松实现自定义图形用户界面。
现在我正在转向其他方式,在我的例子中,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 库都安装了一个同步提供程序来编组调用。