24.Silverlight多线程技术BackgroundWorker的应用,更新ProgressBar控件

        在Silverlight中极其耗时的操作会导致UI进程假死,如果将复杂的操作和UI显示分离开而且我们需要了解这复杂操作的后台进程当前运行的进度如何?这里我们可以使用BackgroundWorker来解决这个问题。

        BackgroundWorker是一个封装了的Thread组件,它能够让用户方便的开启一个独立的线程执行复杂和耗时的后台工作,随时报告当前完成程 度,随时中止异步线程操作,还可以在异步操作状态报告中(ProgressChanged)和异步操作完成后(RunWorkerCompleted)的 响应事件中访问UI线程。

        BackgroundWorker的一些常用的属性、方法和事件如下:

         •属性

             CancellationPending  获取一个值,指示应用程序是否已请求取消后台操作。 
             IsBusy  获取一个值,指示 BackgroundWorker 是否正在运行异步操作。 
             WorkerReportsProgress  获取或设置一个值,该值指示 BackgroundWorker 能否支持报告进度更新。 
             WorkerSupportsCancellation  获取或设置一个值,该值指示 BackgroundWorker 是否支持异步取消。

         •方法

             CancelAsync  请求取消挂起的后台操作。  
             ReportProgress   引发 ProgressChanged 事件。  
             RunWorkerAsync  开始执行后台操作。
  
          •事件

             DoWork  调用 RunWorkerAsync 时发生。 
             ProgressChanged  调用 ReportProgress 时发生。 
             RunWorkerCompleted  当后台操作已完成、被取消或引发异常时发生。

        现在我们清理一下这个组件的运行思路:

        一、首先我们创建一个BackgroundWorker对象实例,然后设置它的属性WorkerReportsProgress、 WorkerSupportsCancellation为ture,为BackgroundWorker实例的DoWork 、 ProgressChanged 、RunWorkerCompleted 三个事件加载相应的事件处理方法。

        二、此时按下“运行按钮”,根据BackgroundWorker的IsBusy属性判断当前对象是否已经正在开始执行后台异步线程,如果未执行异步线 程,则调用RunWorkerAsync()方法开始执行异步线程并且可以传递参数A,此时将触发DoWork事件,在这个事件内部是不能直接操作UI线 程的。此时在DoWork响应时间内部首先判断CancellationPending属性是否为ture,如果为true表示当前已经取消异步进程运 行,否则继续运行需要处理的复杂运算,可以通过e.Argument属性接收到参数A。

        三、在运行复杂运算的过程中,每隔一个时间段执行一次ReportProgress(int percentProgress)函数,传递当前运行完成百分数,此时为参数B,然后触发ProgressChanged事件,在此事件中通过 e.ProgressPercentage属性接收到参数B,更新UI的ProgressBar控件,显示当前的完成进度。

        四、当DoWork内的复杂运算完毕之后为当前DoWork事件的e.Result赋值C,再触发RunWorkerCompleted 事件,此时在RunWorkerCompleted 事件中接受e.Result的值。将结果显示到UI界面上即可。

        下面我们来看一段实例程序源码MainPage.xaml.cs,相关的运行注释在代码中已经注明:

 

 
 
  1. public partial class MainPage : UserControl 
  2. //声明一个BackgroundWorker对象实例 
  3. private BackgroundWorker bgWorker = new BackgroundWorker(); 
  4. public MainPage() 
  5. InitializeComponent(); 
  6. InitBackGroundWorker(); 
  7. //初始化BackgroundWorker的相关属性和加载事件 
  8. public void InitBackGroundWorker() 
  9. //BackgroundWorker是否支持报告执行进度 
  10. bgWorker.WorkerReportsProgress = true
  11. //BackgroundWorker是否支持取消运行异步操作 
  12. bgWorker.WorkerSupportsCancellation = true
  13. //加载DoWork、ProgressChanged、RunWorkerCompleted事件 
  14. bgWorker.DoWork += new DoWorkEventHandler(bgWorker_DoWork); 
  15. bgWorker.ProgressChanged += new ProgressChangedEventHandler(bgWorker_ProgressChanged); 
  16. bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(bgWorker_RunWorkerCompleted); 
  17. //后台异步执行操作的地方 
  18. void bgWorker_DoWork(object sender, DoWorkEventArgs e) 
  19. //获取到传递进来的参数 
  20. string str = e.Argument.ToString(); 
  21. //执行100次循环 
  22. for (int i = 0; i < 100; i++) 
  23. //判断当前BackgroundWorker是否已经被取消了异步操作 
  24. if (bgWorker.CancellationPending == false
  25. //如果没有被取消异步操作,则线程阻塞以下,然后报告给bgWorker_ProgressChanged事件 
  26. Thread.Sleep(50); 
  27. bgWorker.ReportProgress(i + 1); 
  28. e.Result = "3322"
  29. else 
  30. //设置当前已取消异步线程操作 
  31. e.Cancel = true
  32. break; 
  33. //进度改变时触发的事件执行函数,这里显示执行进度 
  34. void bgWorker_ProgressChanged(object sender, ProgressChangedEventArgs e) 
  35. //设置当前进度条的值为事件执行完成程度值 
  36. this.progressBar1.Value = e.ProgressPercentage; 
  37. //异步操作执行完毕之后的处理 
  38. void bgWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
  39.  
  40. //完成异步操作之后检查是否取消了异步操作,弹出相关提示 
  41. if (e.Cancelled == true
  42. MessageBox.Show("取消异步线程操作"); 
  43. else 
  44. MessageBox.Show("异步线程执行完毕" + e.Result); 
  45.  
  46. this.btncancel.Content = "已完成"
  47.  
  48. private void btnrun_Click(object sender, RoutedEventArgs e) 
  49. //如果后台进程未开始运行,则开始运行线程 
  50. if (bgWorker.IsBusy != true
  51. bgWorker.RunWorkerAsync("我是参数"); 
  52.  
  53. private void btncancel_Click(object sender, RoutedEventArgs e) 
  54. //取消异步操作。 
  55. bgWorker.CancelAsync(); 

        本实例采用VS2010+Silverlight 4.0编写,点击 SLBackgroundWorker_Caleung.rar 下载本实例源码。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


如何在Silverlight4(XAML)中绑定IsEnabled属性?我试过简单的IsEnabled=“{BindingABC}”,但这不起作用–MenuItem总是启用.提前感谢您的线索!干杯编辑:有趣的是,当设置Mode=TwoWay时,绑定似乎有效.但是,在菜单项上移动鼠标后,将更新上下文菜单的外观.这是异步工作吗?右键
我正在编写我的第一个vb.net应用程序(但我也会在这里标记c#,因为我确信即使是一个c#人也可以使用类似的.net实现来回答这个问题).我申请的简短说明:我的桌面应用程序将仅在win平台上运行,使用vb.net,它是一个简单的网吧管理软件,在服务器上运行服务器gui,在工作站上运行客户端gui,
ProcessFile()是在UIThread上运行还是在单独的线程上运行.如果它在UIThread上,如何将文件请求和ProcessFile()移动到单独的线程?varxClient=newServiceReference1.Service1SoapClient();xClient.Retrieve_File_Completed+=newEventHandler<ServiceReference1.Retrieve_Fi
我从同行那里听说,对sharepoint的了解对职业生涯有益.我们不在办公室使用sharepoint.所以不知道如何开始.这些是我的新手问题>学习共享点值得努力吗?>学习sharepoint的资源在哪里?>我是否应该考虑开发哪些参考项目?感谢您的意见.解决方法:SharePoint以如此积极的方式改变了我的职业
我正在尝试保存一个类我的类对象的集合.我收到一个错误说明:Thecollectiondatacontracttype‘System.Collections.Generic.Listcannotbedeserializedbecauseitdoesnothaveapublicparameterlessconstructor.Addingapublicparameterlessconstructorwillf
我需要根据Silverlight中的某些配置值设置给定控件的Style.我想有可能从两种可用的样式(静态资源)中选择一个控件样式.我试图做一些像:<TextBoxStyle="{BindingABC}"/>哪里publicstringABC{get{return"{StaticResourceMyStyle}";}}不幸的是,这不起作用.你有
我刚买了第一台Android设备,我喜欢它…我也很喜欢你可以创建自己的应用程序并随意分发它们.我已经阅读了一些关于Monodroid的内容,而且显然微软希望将Silverlight放在这些设备上,尽管没有太多关于它们的信息……但是Moonlight呢?如果Monodroid就像Mono……为什么我们需要它呢?相反
我们的ASP.NET网站允许用户执行各种查询,并根据从数据库查询的结果显示网络图(如UML图).目前,我们正在生成一个位图并显示它.但由于我们需要支持允许用户以交互方式显示/隐藏某些块的功能,因此我们计划使用Silverlight来渲染图形.我们还计划在未来添加更多互动.我有两个问题:>ASP
我正在开发一个Silverlight4应用程序,我已经创建了一个自定义的启动画面.乍一看,自定义启动画面运行良好–非常好.几天后,我开始注意到闪屏不再显示,屏幕仍然是空白.这似乎只发生在我打开多个指向同一个应用程序的IE选项卡/窗口时.前几个将加载正常,而以下选项卡/窗口将保持“白
这是我的XAML:<ImageVerticalAlignment="Center"HorizontalAlignment="Center"Source="{BindingInput,Converter={StaticResourceByteArrayToBitmapConverter}}"><Image.Rend
问候,我有一个ItemsControl,我更改了模板,为绑定的ItemsSource中的每个对象显示一个RadioButton.但是ItemsSource可以为空,当它为空时我想显示默认值.像“绑定列表中没有可供您选择的项目”……我想到的一种方法是将ItemsControl.Visibility设置为Collapsed,并将TextBlock.Vsibi
堆栈溢出的第一个问题……我是C#的新手,但在学习它时却非常直接.几分钟前我才看到这个tutorial.通过各种c#技术阅读WCF,WPF,Silverlight,c#和asp.net,这是很多技术都可以用c#来实现.我将创建一个Web应用程序c#.我认为SilverLight似乎是我最好的选择.该应用程序将拥有一个数
我正在使用MVVM(Model-View-ViewModel)模式编写应用程序,并利用MicrosoftP&P团队的Prism和Unity位.我有一个包含项目列表的视图.这些项包含在ViewModel中的ObservableCollection中,View中的列表框是数据绑定的(ViewModel设置为View的DataContext).在ViewModel中,我有一个运行的
我有一个应用程序,它在首次运行时显示免责声明页面.选择“接受”或“拒绝”后,您再也看不到该页面了.但是,当您在第一次运行后按后退键尝试关闭应用程序时,您将返回免责声明页面,然后再次点击该页面,返回主页面,然后再次退出.这仅在应用程序第一次运行时发生,但我希望应用程序在
我正在尝试在SilverlightforWindowsPhone中使用异步HttpWebRequest.一切都很完美,直到我到达我应该打电话的地方privatestaticManualResetEventallDone=newManualResetEvent(false);...request.BeginGetResponse(newAsyncCallback(GetResponseCallback),request);a
嗨,我有两个Writablebitmap,一个来自jpg,另一个来自png,并使用此方法在循环中混合颜色:privatestaticColorMix(Colorfrom,Colorto,floatpercent){floatamountFrom=1.0f-percent;returnColor.FromArgb((byte)(from.A*amountFrom+to.A*perc
我需要开发一个程序,它包含一个图像(png),中心有一个洞.在这个图像下将有一个框架,我想点击图像的透明孔我可以点击框架内的按钮.我不知道是否有一种方法可以通过图像或其他方式传播点击.谢谢你的帮助解决方法:你在图像上将IsHitTestVisible设置为false,然后点击浏览.
我正在研究一个silverlight应用程序,我发现List没有Find扩展方法说,List<Something>list=newList<Something>(something);list.Remove(list.Find(e=>e.id==10));没有查找扩展方法我错过了什么?解决方法:它不包括在内以减小运行时的大小.建议您使用LINQ扩展,例如First
我试图弄清楚如何设置Path元素的Data属性来获得此类型的软角:alttexthttp://i42.tinypic.com/1rzu6w.jpg现在我只有这样的尖角:alttexthttp://i42.tinypic.com/2eeleah.jpg我尝试用椭圆玩,但我无法得到我想要的东西.谢谢最佳答案:路径的段具有IsSmoothJoin属性,默认为false.
问题我有一个在远程服务器上运行的restfulWeb服务.我已经制作了一个使用它的WP7应用程序,所以我知道它有效.我正在将应用程序移植到SilverlightWeb应用程序并遇到问题.我已经包含了代码的简化版本以及引发的错误.EndGetResponse方法抛出错误.随意询问更多信息.我一直在寻找解