我正在尝试以同步方式显示工作人员任务中的对话框,以便该过程可以根据用户在对话框中的反馈中止或继续该过程。
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
我希望有人可以发现我的错误,或者至少给我一些如何调试它的想法。
答案 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)
之上进行了违规调用。