Prism:通过事件关闭对话框

Prism: Closing Dialog Through Event

我正在尝试构建一个带有加载动画的简单对话框,以便在任务 运行 时显示。 我使用 Prism IDialogServiceIEventAggregator 但是,我得到一个 System.InvalidOperationException,因为带有动画的对话框会弹出,但任务完成后永远不会关闭。

异常消息是:调用线程无法访问此对象,因为另一个线程拥有它。

可以通过单击 X 按钮关闭对话框,没有任何问题。

在非异步情况下,我可以根据需要打开和关闭对话框,但我无法全神贯注地执行此异步操作。

这是我到目前为止的想法,导致了上述错误。

WarehouseViewModel.cs

数据已加载并显示对话框。

        private async void LoadData()
        {
            await WarehouseListLoad().ContinueWith(t => { _eventAggregator.GetEvent<LoadingFinishedEvent>().Publish(true); });
        }

        private async Task WarehouseListLoad()
        {
            _dialogService.ShowDialog("LoadingDialogView");
            List<Warehouse> warehouses = await Task.Run(() =>
            {
                List<Warehouse> list = _warehouseStore.GetAll();
                return list;
            });
        }

LoadingDialogViewModel.cs

侦听 LoadingFinishedEvent 并调用 RequestClose。


        public event Action<IDialogResult> RequestClose;

        public LoadingDialogViewModel(IEventAggregator eventAggregator)
        {
            eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null));
        }

        protected virtual void CloseDialog(string parameter)
        {
            RaiseRequestClose(new DialogResult(ButtonResult.None));
        }

        public virtual void RaiseRequestClose(IDialogResult dialogResult)
        {
            try
            {
                RequestClose?.Invoke(dialogResult);
            }
            catch(System.InvalidOperationException ex)
            {
                Debug.WriteLine(ex.Message);
                //System.InvalidOperationException: The calling thread cannot access this object because a different thread owns it
            }
        }

您要么想要 Subscribe 在 UI-Thread

eventAggregator.GetEvent<LoadingFinishedEvent>().Subscribe(close => CloseDialog(null), ThreadOption.UIThread);

或使用 Dispatcher 调用 RequestClose

Application.Current.Dispatcher.Invoke( () => RequestClose?.Invoke(dialogresult) );

或者您删除 Task.Run 并使 GetAll 实际上是异步的...