使用MVVM从工作任务显示同步对话框会产生System.InvalidOperationException

时间:2018-02-06 12:55:10

标签: c# wpf mvvm dialog mahapps.metro

我正在尝试以同步方式显示工作人员任务中的对话框,以便该过程可以根据用户在对话框中的反馈中止或继续该过程。

sys.excepthook = exception_logging
从UI线程调用

public Task StartBackgroundTask() { var measurementResult = DoQuickPreMeasurement(); if(measurementSuccessful == false) { var task = dialogService.ShowMeasurementFailed("Measurement failed because of reason XYZ, continue?!"); var dialogResult = task.Result; if (dialogResult == MessageDialogResult.Negative) return Task.CompletedTask; // this ends the background run } Task.Run(()=>{ LongRunningTask();}); } 。当我运行它时,我得到以下异常,我无法解决:

StartBackgroundTask()

我正在使用MvvmLight并尝试使用各种不同的方式调用UI调度程序(也使用 Exception thrown: 'System.InvalidOperationException' in WindowsBase.dll ("The calling thread cannot access this object because a different thread owns it.") ),但是还没有成功使用它。

这是DispatcherHelper中的缩减代码:

DialogService

为了完整性:public class DialogService { private IDialogCoordinator dialogCoordinator; private ViewModelBase parentViewModel; private BaseMetroDialog pleaseCloseLidDialog; private BaseMetroDialog openLidPrintingAbortedDialog; private BaseMetroDialog shutDownDialog; public DialogService(IDialogCoordinator dialogCoordinator, ViewModelBase parentViewModel) { this.dialogCoordinator = dialogCoordinator; this.parentViewModel = parentViewModel; } public Task<MessageDialogResult> ShowMeasurementFailed(string message) { var metroWindow = (MetroWindow)(Application.Current.MainWindow); return metroWindow.Invoke(() => { var mySettings = new MetroDialogSettings() { AffirmativeButtonText = "Continue", NegativeButtonText = "Abort" }; return ((MetroWindow)(Application.Current.MainWindow)).ShowMessageAsync( "Measurement has finished", "Result: " + message + ".\n\nContinue?", MessageDialogStyle.AffirmativeAndNegative, mySettings); //return dialogCoordinator.ShowMessageAsync(parentViewModel, // "Measurement has finished", // "Result: " + message + ".\n\nContinue?", // MessageDialogStyle.AffirmativeAndNegative, // mySettings); }); } } IDialogCoordinator我正在使用StructureMap注入MahApps实现(parentViewModel)以及主窗口的VM,这对于其他对话框很有效。服务(我在上面的例子中省略了):

DialogCoordinator

我希望有人可以发现我的错误,或者至少给我一些如何调试它的想法。

1 个答案:

答案 0 :(得分:0)

似乎是对

的调用
var metroWindow = (MetroWindow)(Application.Current.MainWindow);

是违法的电话。我现在已经修改了方法ShowMeasurementFailed,如下所示,它现在可以工作:

public Task<MessageDialogResult> ShowMeasurementFailed(string message)
{
    var dispatcher = DispatcherHelper.UIDispatcher; // get UI dispatcher from MvvmLight
    return dispatcher.Invoke(() =>
    {
        var mySettings = new MetroDialogSettings()
        {
            AffirmativeButtonText = "Continue",
            NegativeButtonText = "Abort"
        };

        return dialogCoordinator.ShowMessageAsync(parentViewModel,
            "Measurement has finished",
            "Result: " + message + ".\n\nContinue?",
            MessageDialogStyle.AffirmativeAndNegative,
            mySettings);
    });
}

请注意,调度程序的使用现在与我以前的尝试相反。也许我在测试期间仍然在我的代码中的(MetroWindow)(Application.Current.MainWindow)之上进行了违规调用。