我使用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