我使用MVVM光与有其中用于用于显示一个对话框接口IDialogService。此接口已经在App.xaml.cs已经实现C#等待关于GUI线程和捕获异常WPF
一种具体方法是有趣:
public Task<bool> ShowMessage(string message, string title, string buttonConfirmText,
string buttonCancelText,
Action<bool> afterHideCallback)
{
return Task.Factory.StartNew(() =>
{
var style = new Style(typeof(MessageBox));
style.Setters.Add(new Setter(MessageBox.OkButtonContentProperty, buttonConfirmText));
style.Setters.Add(new Setter(MessageBox.CancelButtonContentProperty, buttonCancelText));
var result = MessageBox.Show(_GetActiveWindow(), message, title,
MessageBoxButton.OKCancel,
MessageBoxImage.Question, style) == MessageBoxResult.OK;
if (afterHideCallback != null) afterHideCallback(result);
return result;
凡_currentTaskScheduler = TaskScheduler.FromCurrentSynchronizationContext();
在OnStartup
Task<bool> ShowMessage(string message, string title, string buttonConfirmText, string buttonCancelText, Action<bool> afterHideCallback);
物的方法来实现
所以平时我们应该把这种方法与前面的await获得布尔值:
var result = await DialogService.ShowMessage(
Resources.Areyousure,Resources.Warning,
Resources.Yes, Resources.No, null);
到目前为止好。现在我有一个包装方法来执行代码并捕获异常,然后显示带有错误的消息框。
public bool TryCatchExecution(Action action, string successMessage = null)
{
try
{
action();
if (!string.IsNullOrEmpty(successMessage))
DialogService.ShowMessage(successMessage, Resources.Success);
return true;
}
catch (LogException ex)
{
DialogService.ShowError(ex.Error.LogMessage, Resources.Error, Resources.OK, null);
}
catch (Exception ex)
{
DialogService.ShowError(ex.Message, Resources.Error, Resources.OK, null);
}
return false;
}
现在我有一个问题。如果我使用样本A,GUI线程在行var result = DialogService.ShowMessage
处被阻止。但是,如果我使用示例B中的GUI线程未阻止,则会显示消息框,并且所有内容都按照它应该的方式工作。直到我得到一个异常。代码无例外。错误是“类型的第一个机会异常‘System.ServiceModel.FaultException`1’出现在mscorlib.dll”和应用程序崩溃。正如我一直在阅读的,这与SynchronizationContext有关。
//Sample A
private void ExecuteDeleteCommand()
{
TryCatchExecution(() =>
{
var result = DialogService.ShowMessage(
Resources.Areyousure,
Resources.Warning,
Resources.Yes,
Resources.No, null).Result;
if (!result) return;
_datalayer.DeleteField(FieldSelected);
Refresh();
FieldEdit = new MsgSqlFieldMapping();
RaisePropertyChanged("SqlRepository");
DialogService.ShowMessage(Resources.OperationSucceeded, Resources.Success);
});
}
//Sample B
private void ExecuteDeleteCommand()
{
TryCatchExecution(async() =>
{
var result =await DialogService.ShowMessage(
Resources.Areyousure,
Resources.Warning,
Resources.Yes,
Resources.No, null);
if (!result) return;
_datalayer.DeleteField(FieldSelected);
Refresh();
FieldEdit = new MsgSqlFieldMapping();
RaisePropertyChanged("SqlRepository");
await DialogService.ShowMessage(Resources.OperationSucceeded, Resources.Success);
});
}
请帮我理解这里发生了什么,以及如何处理它。
日Thnx了很多。
我已经忘了提,我使用.net4.5框架。 – Gintaras