我正在尝试在执行异步操作时显示对话框。
我的架构之前是基于事件的,因为我希望用户可以轻松实现自定义图形用户界面。
现在我正在寻找其他方法,在我的情况下,返回同步方法的类型,而不是包含数据的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 可能在哪里,我不知道知道。
谢谢!
答案 0 :(得分:1)
正如评论中所讨论的,您只是使用错误的Control引用来调用BeginInvoke()。该对话框无法正常工作,但尚未创建。重要的是,在窗口提交给特定线程之前,.NET无法确定哪个线程拥有该窗口。在调用Show()之前不会发生这种情况。
但是任何其他窗口都可以,你必须已经拥有一个窗口,因为显示没有所有者的对话框是不合法或不实际的。您必须提供构造函数或属性,以便客户端代码可以提供对此类窗口的引用。任何人都会这样做,应用程序的主窗口是一个实用的选择。
通过在构造函数中复制Synchronization.Current的值,可以将类与UI实现完全分离(在此处显示对话框时不实用)。您稍后可以调用其Post()方法。 .NET中的所有UI类库都安装了一个同步提供程序,该提供程序将封送该调用。