使用线程新建窗体

项目中需要一个公用的进度条窗体.大家知道在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. 重温 Win32 API ----- 截屏指定窗体并打印

    朋友说在一个VC++6.0开发的项目中要增加打印窗体的功能,让帮忙写个代码供其调用. 这么老的IDE当然不想碰了,并且也不喜欢MFC笨拙不清晰的封装.所以决定採用纯Win32 API,然后用C++类简 ...

  2. javasrcipt日期一些方法和格式转化

    Js获取当前日期时间及其它操作 var myDate = new Date();myDate.getYear();        //获取当前年份(2位)myDate.getFullYear();   ...

  3. asp.net js调用后台方法

    先前网上百度了很多 ,大致都一样 但是不太详细,总是不成功,然后试了很多,把经验发给大家看看 前台js function aa() { //这里可以写你要带的参数用隐藏域放起来 __doPostBac ...

  4. 南阳师范学院ACM官方博客使用说明

    登录之后跳到如下页面: 点击博客进入如下页面: 这里每个人都有一个专栏,大家可以把自己写得博客放到自己的专栏下,同时也可以查看其他人写的博客,相互交流! 在发表博客的时候,选择个人分类中自己的专栏即可 ...

  5. D1-Linux-CentOS学习打卡

    从一月底开始萌生了想在继续学Python的时候,学一门新的操作系统. 在看很多程序员的JD时,很多都要求熟悉LINUX,并且奔方法里面也提到了在LINUX下的编程. ----------------- ...

  6. linux操作系统死机处理办法

    这个方法可以在各种情况下安全地重启计算机.大家在键盘上找,可以找到一个叫做“Sys Rq”的键,在台机的键盘上通常与 Prt Sc 共键,在笔记本可能在其他位置,如 Delete.以台机为例,要使用这 ...

  7. java学习之xml

    xml的处理有两种方式dom和Sax 其中dom有3套api ,分别是dom和jdom和dom4j package com.gh.xml; import java.io.File; import ja ...

  8. poj 2363 Blocks(暴力)

    题目链接:http://poj.org/problem?id=2363 思路分析:由于数据较小,采用暴力搜索法.假设对于矩形边长 1 <= a <= b <= c <= N; ...

  9. Poj 2092 Grandpa is Famous(基数排序)

    题目链接:http://poj.org/problem?id=2092 思路分析:先统计数据,在根据Count降序排序,Count相等时按照Num升序排序:再输出Count第二大的所有Num: 代码如 ...

  10. php调用com组件配置 以openoffice为例

    什么是com组件? COM构架下,人们可以开发出各种各样的功能专一的组件,然后将它们按照需要组合起来,构成复杂的应用系统.COM与语言,平台无关的特性使所有的程序员均可充分发挥自己的才智与专长编写组件 ...