我有DialogViewModel
类async Task LoadData()
方法。此方法异步加载数据并显示此对话框,通知用户有关加载的信息。这是代码:
try
{
var dialog = new DialogViewModel();
var loadTask = dialog.LoadData();
WindowManager.ShowDialog(dialog);
await loadTask;
}
catch (Exception ex)
{
Logger.Error("Error in DialogViewModel", ex);
// Notify user about the error
}
当LoadData
抛出异常时,在用户退出对话框之前不会处理它。这是因为在调用await
时处理了异常,并且在WindowManager.ShowDialog(dialog)
完成之前不会发生异常。
显示异步加载对话框的正确方法是什么?我试过这种方式:
LoadData()
,构造函数或类似内容中调用OnShow()
。但如果我需要在没有任何数据的情况下显示此对话框,这将无法工作await LoadData()
。这样用户必须在实际看到窗口之前等待数据加载,但我希望窗口能够立即显示加载指示器。答案 0 :(得分:0)
为什么有明确的公开LoadData
方法?
如果必须这样做,那么使用带有Task<T>
的{{1}}异步地在构造函数内部执行它,以通过检查返回任务上的ContinueWith
属性来处理生成的任何异常。
这将解决您已突出显示的两个问题。
下面显示了一个非常简单的示例,显然您的实施将更加复杂。
IsFaulted
或者,如果您不想明确使用public class DialogViewModel
{
private Task _task;
public DialogViewModel()
{
var context = TaskScheduler.FromCurrentSynchronizationContext();
_task = Task.Factory.StartNew(() =>
{
var data = GetDataCollection();
return data;
})
.ContinueWith(t =>
{
if (t.IsFaulted)
{
HasErrored = true;
ErrorMessage = "It's borked!";
}
else
{
Data = t.Result;
}
}, context);
}
public IEnumerable<string> Data { get; private set; }
public bool HasErrored { get; private set; }
public string ErrorMessage { get; private set; }
private static IEnumerable<string> GetDataCollection()
{
return new List<string>()
{
"John",
"Jack",
"Steve"
};
}
}
并希望使用async \ await功能,则可以使用稍微不同的方法,因为您不能将async \ await与类构造函数一起使用:
Task<T>