运行耗时的任务时,我想显示一个带有Indeterminate="True"进度栏的简单WPF窗口。

我已经按照-Reed Copsey的this示例实现了我的解决方案。

该过程完成后,我需要关闭窗口。
我的猜测是要实现这一点,我要么需要杀死线程,要么关闭view(window)。

不幸的是,两种方式都给我以下错误:

1)在线程上调用Abort():

窗口已关闭,这是正确的,但是我仍然遇到以下错误:

由于代码已优化或 native 框架位于调用堆栈顶部,因此无法评估表达式

2)View.Close():

调用线程无法访问该对象,因为其他线程拥有它。

所需的逻辑需要在StopThread()方法中实现,无论如何,我都可以优雅地关闭Window:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Threading;
using Microsoft.Practices.Composite.Presentation.Commands;

namespace ProgressBar
{
    public class ProgressBarViewModel
    {
        public DelegateCommand<object> CloseCommand { get; set; }
        Thread newWindowThread;

        string _closeButton;
        public string CloseButton
        {
            get { return _closeButton; }
            set { _closeButton = value; }
        }

        ProgressBarView _view;
        public ProgressBarView View
        {
            get { return _view; }
            set { _view = value; }
        }

        public ProgressBarViewModel(ProgressBarView view)
        {
                CloseButton = "Close";
                CloseCommand = new DelegateCommand<object>(CloseForm);

                View = view;
                View.Closing +=new System.ComponentModel.CancelEventHandler(View_Closing);
                View.DataContext = this;
        }

        public void View_Closing(object sender,CancelEventArgs e)
        {
            StopThread();
        }

        public void CloseForm(object p)
        {
            StopThread();
        }

        private void StopThread()
        {
            try
            {
                //View.Close();
                newWindowThread.Abort();
            }
            catch (Exception eX)
            {
                Debugger.Break();
                //Getting an error when attempting to end the thread:
                //Unable to evaluate expression because the code is optimized or a native frame is on top of the call stack
            }
        }

        public void ShowProgress()
        {
                newWindowThread = new Thread(new ThreadStart(() =>
                {
                    ProgressBarView tempWindow = new ProgressBarView();
                    tempWindow.DataContext = this;
                    tempWindow.Show();
                    System.Windows.Threading.Dispatcher.Run();
                }));

                newWindowThread.SetApartmentState(ApartmentState.STA);
                newWindowThread.IsBackground = true;
                newWindowThread.Start();
        }
    }
}

最佳答案

您应该做的是将您的操作封装在自己的类中,并在操作完成时引发一个事件(或者您要关闭 View )

事件处理程序将需要使用Dispatcher在与 View 相同的线程中运行close()

关于c# - 在单独的线程中显示WPF ProgressBar窗口,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12953064/

10-15 16:52
查看更多