使用线程新建窗体

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

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

   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();
}

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

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

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

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

首先设置一个公共变量:

public static bool IsClsoeProgeressBar = true;

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

/// <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();
}
}
}
}

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

   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)
{
}

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

         /// <summary>
/// 显示进度条 线程
/// </summary> public static void BeginProgressBar()
{
IsClsoeProgeressBar = false;
} /// <summary>
/// 结束进度条
/// </summary>
public static void EndProgressBar()
{
//cts.Cancel();
IsClsoeProgeressBar = true;
}

还有一个比较好的方法:

 #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. WPF 绕圈进度条(二)

    一 以前的方案 以前写过一个圆点绕圈的进度条,根据参数圆点个数和参数每次旋转角度,主要是在cs文件中动态添加圆点,通过后台定时器,动态设置角度后用正弦余弦计算(x,y)的位置. 此方案优点:动态添加L ...

  2. WPF Canvas实现进度条

    原文:WPF Canvas实现进度条 先看效果图: 思路: 一个Canvas做背景,一个Canvas用来显示进度,图片放在显示进度的Canvas中,靠右设置为图片本身宽度一半的距离,视觉上实现以图片中 ...

  3. Winform之跨线程访问控件(在进度条上显示字体)

    此文章对于遇到必须使用线程但是没有办法在线程内操作控件的问题的处理  有很好的解决方案(个人认为的.有更好的方案欢迎交流.) 在做跨线程访问之前我们先了解下我们所做的需要达到的效果: 这个是批量的将x ...

  4. WPF自定义控件第一 - 进度条控件

    本文主要针对WPF新手,高手可以直接忽略,更希望高手们能给出一些更好的实现思路. 前期一个小任务需要实现一个类似含步骤进度条的控件.虽然对于XAML的了解还不是足够深入,还是摸索着做了一个.这篇文章介 ...

  5. WPF 实现圆形进度条

    项目中用到圆形进度条,首先就想到使用 ProgressBar 扩展一个,在园子里找到迷途的小榔头给出的思路和部分代码,自己加以实现. 进度小于60显示红色,大于60则显示绿色.效果如下: 基本思路: ...

  6. WPF好看的进度条实现浅谈(效果有点类似VS2012安装界面)

    为了界面友好,一般的操作时间较长时,都需要增加进度条提示.由于WPF自带的进度条其实不怎么好看,而且没啥视觉效果.后来,装VS2012时,发现安装过程中进度条效果不错,于是上网查了资料.学习了Mode ...

  7. WPF弹出进度条

    环境:vs2015 ,.net 4.6 源码地址:https://pan.baidu.com/s/1FoujUMst1luomPf0ZfCLUQ 提取码:trzj 说明: 1.进度条是在winFrom ...

  8. WPF 绕圈进度条(一)

    在设计界面时,有时会遇到进度条,本次讲解如何设计自定义的绕圈进度条,直接上代码: 1.控件界面 <UserControl x:Class="ProgressBarControl&quo ...

  9. WPF的ProgressBar进度条

    1. ProgressBar常用属性 1.1.  Minimum:进度条的最小值,一般为 0 1.2. Maximum:进度条的最大值,一般为100 或者是 某一个数, 如复制文件时,总文件数等 1. ...

随机推荐

  1. HDU 2962 Trucking

    题目大意:给定无向图,每一条路上都有限重,求能到达目的地的最大限重,同时算出其最短路. 题解:由于有限重,所以二分检索,将二分的值代入最短路中,不断保存和更新即可. #include <cstd ...

  2. java学习之JDBC

    之前学习了数据库原理,上学期也学了oracle数据库,我的学习视频上是讲的mysql数据库,其实都差不多,复习了下sql知识,数据库的学习就没有写下来了,就从Java怎么操作数据库开始吧. 因为这年过 ...

  3. Installing on CentOS/RHEL / KB forum / Ajenti

    Installing on CentOS/RHEL / KB forum / Ajenti Ajenti → KB → Installation Is it?: Inappropriate Spam ...

  4. android adb经常使用的命令

    1.adb--- 订购屏幕截取  :adb shell screencap -p | sed 's/\r$//' > outputs.png 2.jni ---命令    :$NDK/ndk-b ...

  5. Java多线程之非线程安全

    在Java多线程中我会重点总结五个如下的技术点: 1.非线程安全是如何出现的 2.synchronized对象监视器为Objec时的使用 3.synchronized对象监视器为Class时的使用 4 ...

  6. c#程序添加其他网站的webservice引用。

    前言: 有A网站,B网站两个网站独立运行.某一天,需要两个网站进行合作来完成一件事,比如用A网站接收一些数据进行处理,存入中转数据库,B网站定时去取数据进入自己的系统进行处理. 可能我们会先想到在B网 ...

  7. [Swust OJ 795]--Penney Game

    题目链接:http://acm.swust.edu.cn/problem/795/ Time limit(ms): 1000 Memory limit(kb): 65535   Description ...

  8. (转)内核线程对象--Event事件对象

    在所有的内核对象中,事件内核对象是个最基本的对象.事件能够通知一个操作已经完成. 客户机和一个服务器,它们之间需要互相进行通信例子(vs2008 ) 事件内核对象的组成 一个使用计数(与所有内核对象一 ...

  9. Ownership qualifiers of Objective-C: In Details

    虽然这里讲的大部分知识以前都看过,但是时不时出现某些点让我如茅塞顿开: 以前经常会忘记一些细节,这篇文章可以更好的理解细节,巩固知识体系. Ownership qualifiers In Object ...

  10. 关于MooTools你应该熟知的6个基本知识

    MooTools是一个精简.模组化同时也面向对象的JavaScript框架,它设计给中等和进阶的JavaScript开发人员使用.使用 MooTools优美.详细而条理分明的API,可让你写出强大.富 ...