使用线程新建窗体

项目中需要一个公用的进度条窗体.大家知道在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 2815 Mod Tree

    不会,先搁着…… http://blog.csdn.net/acm_cxlove/article/details/7832197

  2. hdoj 1247 Hat’s Words(字典树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1247 思路分析:题目要求找出在输入字符串中的满足要求(该字符串由输入的字符串中的两个字符串拼接而成)的 ...

  3. /export/App/zz/phantomjs-1.9.7-linux-x86_64/bin

    /export/App/zz/phantomjs-1.9.7-linux-x86_64/bin

  4. 移动开发语言Swift

    苹果公布了全新的编程语言Swift,Swift继承了Objective-C语言特性,并从Python和Java Script中长处,使Swift更易读.未来swift编程语言的会特大广大的使用 Swi ...

  5. jQuery也能舞出绚丽的界面(完结篇)

    ThematicMap又增加了两种Chart类型,现在总算是齐全了,效果也出来了,与大家分享一下: 1.MultiSelect选择界面: 颜色框是可以选择颜色的: 2.生成的饼图效果: 3.生成的柱状 ...

  6. css优先级及权重值

    优先级: 外部样式表 内部样式表(位于<head>标签内部 内联样式(在HTML元素内部)优先权最高 内联样式>内部样式=外部样式(看具体引入位置,解析的先后) 权重值: 第一等:内 ...

  7. 界面调试工具Reveal的使用介绍

    Reveal 注: 此处介绍Reveal,其中大部分内容来自于唐巧的<iOS开发进阶>一书,以此说明. 如何使用Reveal进行模拟器调试,只需进行以下三个步骤即可. 1. 创建.lldb ...

  8. java volatile关键字的理解

    转载:http://shmilyaw-hotmail-com.iteye.com/blog/1672779 一个多线程的示例引发的问题 在讨论这个关键字之前先看一个多线程的示例代码: public c ...

  9. Windows下配置Mysql

    这里说的配置Mysql,是在安装时进行的,请先查看:Windows平台下安装Mysql 紧接上文,安装完成后将配置选项打上对勾,按下“Finish”,出现下面的界面,这里有一个很好的功能,mysql配 ...

  10. 使用python操作RabbitMQ,Redis,Memcache,SQLAlchemy 其一

    一.概念 1.Memcached     Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提高动态 ...