首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

运用线程新建WPF窗体(公用进度条窗体)

2013-09-06 
使用线程新建WPF窗体(公用进度条窗体)使用线程新建窗体项目中需要一个公用的进度条窗体.大家知道在wpf中,

使用线程新建WPF窗体(公用进度条窗体)

使用线程新建窗体

项目中需要一个公用的进度条窗体.大家知道在wpf中,有两个线程,一个是UI线程,另一个是监听线程(一直监听用户的输入).如果我们后台有阻塞UI线程的计算存在,那么界面上的比如进度条什么动态的UI都会被因为阻塞而静止不动.

所以我的想法就是新起一个线程来负责进度条窗体的显示与关闭,具体实现代码如下:

 

运用线程新建WPF窗体(公用进度条窗体)
   private static Thread th;        /// <summary>        /// 显示进度条 线程        /// </summary>        /// <param name="msg">进度条界面需要显示的文字</param>        /// <param name="sleep">增加进度条存在的延迟时间,单位为毫秒</param>        public static void BeginProgressBar(string msg, int sleep)        {            try            {                if (th == null || th.ThreadState == ThreadState.Aborted)                {                    th = new Thread(new ThreadStart(() =>                   {                       WinProgressBar win = new WinProgressBar();                       win.Tips = msg;                       win.Topmost = true;                       win.Show();                       System.Windows.Threading.Dispatcher.Run();                   }));                    th.SetApartmentState(ApartmentState.STA);                    th.IsBackground = true;                }                if (th.ThreadState != ThreadState.Background || th.ThreadState == ThreadState.Unstarted || th.ThreadState != ThreadState.Running)                {                    th.Start();                }            }            catch (Exception)            {                th = new Thread(new ThreadStart(() =>                {                    WinProgressBar win = new WinProgressBar();                    win.Tips = msg;                    win.Topmost = true;                    win.Show();                    System.Windows.Threading.Dispatcher.Run();                }));                th.SetApartmentState(ApartmentState.STA);                th.IsBackground = true;                th.Start();            }            Thread.Sleep(sleep);        }        /// <summary>        /// 结束进度条        /// </summary>        public static void EndProgressBar()        {            if (th.IsAlive)                th.Abort();        }
运用线程新建WPF窗体(公用进度条窗体)

 

呵呵,大家仔细分析下代码看有什么问题没有?而你们又有什么好的解决方案没有?

在使用过程中发现一个很严重的问题,出现一个进度条窗体,系统内存就会增大一点,到最后要么卡死,要么自动退出.

     原来在多线程程序运行中,由用户取消操作是一种非常常见的场景,比如用户使用windows资源管理器在当前文件夹中搜索文件时,可以通过点击其它文件夹而取消搜索。
中途停止一个线程的执行,通常用Thread.Abort方法,但这种方式会造成程序涉及的数据完整性受到破坏,线程所占用的一些系统资源(比如文件句柄等)也可能无法完成。比较合理的方式是外界提出"取消操作"的请求,然后由线程自身来决定如何处理这一请求。
在设计多线程程序时,可设置一个用于接收外部取消消息的属性,然后在线程函数中分阶段地检测这一属性,每个阶段的检查点由软件开发者确定,并且决定线程如何优雅退出。

所以对上述代码进行了改进

首先设置一个公共变量:

 public static bool IsClsoeProgeressBar = true;

然后在进度条窗体中实时读这个数据

 

运用线程新建WPF窗体(公用进度条窗体)
/// <summary>    /// WinProgressBar.xaml 的交互逻辑    /// </summary>    public partial class WinProgressBar : Window    {        public string Tips { get; set; }        DispatcherTimer timer;        public WinProgressBar()        {            InitializeComponent();            timer = new DispatcherTimer();            timer.Interval = TimeSpan.FromMilliseconds(200);            timer.Tick += new EventHandler(timer_Tick);            timer.IsEnabled = true;            this.Topmost = true;            //this.Loaded += delegate            //{            //    if (this.Tips != "")            //        tbTips.Text = this.Tips;            //};        }        void timer_Tick(object sender, EventArgs e)        {            if (Common.CommWindow.IsClsoeProgeressBar)            {                if (this.Visibility == Visibility.Visible)                {                    progressBar1.IsIndeterminate = false;                    this.Hide();                }            }            else            {                if (this.Visibility != Visibility.Visible)                {                    progressBar1.IsIndeterminate = true;                    this.Show();                }                       }        }    }
运用线程新建WPF窗体(公用进度条窗体)

 

然后在系统加载的时候,创建这个进度条窗体

运用线程新建WPF窗体(公用进度条窗体)
   try            {                Thread th = new Thread(new ThreadStart(() =>                {                    WinProgressBar win = new WinProgressBar();                   // win.Tips = msg;                    win.Show();                    System.Windows.Threading.Dispatcher.Run();                }));                th.SetApartmentState(ApartmentState.STA);                th.IsBackground = true;                th.Start();            }            catch (Exception)            {            }
运用线程新建WPF窗体(公用进度条窗体)

我们只需改变公共变量来控制窗体的显示与隐藏

运用线程新建WPF窗体(公用进度条窗体)
         /// <summary>        /// 显示进度条 线程        /// </summary>          public static void BeginProgressBar()        {            IsClsoeProgeressBar = false;        }        /// <summary>        /// 结束进度条        /// </summary>        public static void EndProgressBar()        {            //cts.Cancel();            IsClsoeProgeressBar = true;        }
运用线程新建WPF窗体(公用进度条窗体)

还有一个比较好的方法:

运用线程新建WPF窗体(公用进度条窗体)
 #region Methods        /// <summary>        /// 一个耗时的任务        /// </summary>        private void BigTask()        {            Thread.Sleep(3000);        }        private void button1_Click(object sender, RoutedEventArgs e)        {            MyProgressBar(BigTask);        }        private void MyProgressBar(Action mywork)        {            var worker = new BackgroundWorker();            var window = new BusyWindow();            worker.DoWork += (s, e2) => { mywork(); };            worker.RunWorkerCompleted += (s, e2) =>            {                MessageBox.Show("任务已经完成");                window.Close();            };            worker.RunWorkerAsync();            window.Show();        }        #endregion
运用线程新建WPF窗体(公用进度条窗体)

这个由网友热情的沙漠提供,也很不错,大家可以参考下


1楼u011938611昨天 21:46
有用,非常好,收了。谢谢!

热点排行