稳扎稳打Silverlight(25) - 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool

2016-08-20 10:57:29来源:http://webabcd.blog.51cto.com/1787395/343906作者:webabcd人点击


[索引页][源码下载]
稳扎稳打Silverlight(25) - 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool作者:webabcd介绍Silverlight 2.0使用Thread, Timer, BackgroundWorker, ThreadPool来实现多线程开发 Thread - 用于线程的创建和控制的类 Timer - 用于以指定的时间间隔执行指定的方法的类 BackgroundWorker - 用于在单独的线程上运行操作 ThreadPool - 线程池的管理类在线DEMOhttp://webabcd.blog.51cto.com/1787395/342779示例1、Thread.xaml

<UserControl x:Class="Silverlight20.Thread.Thread" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel HorizontalAlignment="Left" Margin="5"> <TextBlock x:Name="txtMsg" /> </StackPanel> </UserControl>

Thread.xaml.cs

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Silverlight20.Thread { public partial class Thread : UserControl { string result = ""; public Thread() { InitializeComponent(); Demo(); } void Demo() { /* * Thread - 用于线程的创建和控制的类 * Name - 线程名称 * IsBackground - 是否是后台线程(对于Silverlight来说,是否是后台线程没区别) * Start(object parameter) - 启动后台线程 * object parameter - 为后台线程传递的参数 * IsAlive - 线程是否在执行中 * ManagedThreadId - 当前托管线程的唯一标识符 * ThreadState - 指定线程的状态 [System.Threading.ThreadState枚举] * Abort() - 终止线程 */ // DoWork 是后台线程所执行的方法(此处省略掉了委托类型) // ThreadStart 委托不可以带参数, ParameterizedThreadStart 委托可以带参数 System.Threading.Thread thread = new System.Threading.Thread(DoWork); thread.Name = "ThreadDemo"; thread.IsBackground = true; thread.Start(1000); result += thread.IsAlive + "/r/n"; result += thread.ManagedThreadId + "/r/n"; result += thread.Name + "/r/n"; result += thread.ThreadState + "/r/n"; // thread.Join(); 阻塞调用线程(本例为主线程),直到指定线程(本例为thread)执行完毕为止 // 阻塞调用线程(本例为主线程) // 如果指定线程执行完毕则继续(本例为thread执行完毕则继续) // 如果指定线程运行的时间超过指定时间则继续(本例为thread执行时间如果超过5秒则继续) // 返回值为在指定时间内指定线程是否执行完毕(本例中thread的执行时间为1秒,所以会返回true) if (thread.Join(5000)){ result += "指定线程在5秒内执行完毕/r/n"; } txtMsg.Text = result; } void DoWork(object sleepMillisecond) { System.Threading.Thread.Sleep((int)sleepMillisecond); result += "新开线程执行完毕/r/n"; } } }

2、Timer.xaml

<UserControl x:Class="Silverlight20.Thread.Timer" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel HorizontalAlignment="Left" Margin="5"> <TextBlock x:Name="txtMsg" /> </StackPanel> </UserControl>

Timer.xaml.cs

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Silverlight20.Thread { public partial class Timer : UserControl { System.Threading.SynchronizationContext _syncContext; // Timer - 用于以指定的时间间隔执行指定的方法的类 System.Threading.Timer _timer; private int _flag = 0; public Timer() { InitializeComponent(); // UI 线程 _syncContext = System.Threading.SynchronizationContext.Current; Demo(); } void Demo() { // 输出当前时间 txtMsg.Text = DateTime.Now.ToString() + "/r/n"; // 第一个参数:定时器需要调用的方法 // 第二个参数:传给需要调用的方法的参数 // 第三个参数:此时间后启动定时器 // 第四个参数:调用指定方法的间隔时间(System.Threading.Timeout.Infinite 为无穷大) _timer = new System.Threading.Timer(MyTimerCallback, "webabcd", 3000, 1000); } private void MyTimerCallback(object state) { string result = string.Format("{0} - {1}/r/n", DateTime.Now.ToString(), (string)state); // 调用 UI 线程。不会做自动线程同步 _syncContext.Post(delegate { txtMsg.Text += result; }, null); _flag++; if (_flag == 5) _timer.Change(5000, 500); // 执行5次后,计时器重置为5秒后启动,每5毫秒的间隔时间执行一次指定的方法 else if (_flag == 10) _timer.Dispose(); // 执行10次后,释放计时器所使用的全部资源 } } }


3、BackgroundWorker.xaml

<UserControl x:Class="Silverlight20.Thread.BackgroundWorker" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel HorizontalAlignment="Left" Margin="5"> <StackPanel Orientation="Horizontal" Margin="5"> <Button x:Name="btnStart" Content="开始" Margin="5" Click="btnStart_Click" /> <Button x:Name="btnCancel" Content="取消" Margin="5" Click="btnCancel_Click" /> </StackPanel> <StackPanel Margin="5"> <TextBlock x:Name="txtProgress" Margin="5" /> <TextBlock x:Name="txtMsg" Margin="5" /> </StackPanel> </StackPanel></UserControl>

BackgroundWorker.xaml.cs

/* * 演示用 BackgroundWorker 在后台线程上执行耗时的操作 * 按“开始”键,开始在后台线程执行耗时操作,并向UI线程汇报执行进度 * 按“取消”键,终止后台线程 * BackgroundWorker 调用 UI 线程时会自动做线程同步 */ using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Silverlight20.Thread { public partial class BackgroundWorker : UserControl { // BackgroundWorker - 用于在单独的线程上运行操作。例如可以在非UI线程上运行耗时操作,以避免UI停止响应 System.ComponentModel.BackgroundWorker _backgroundWorker; public BackgroundWorker() { InitializeComponent(); BackgroundWorkerDemo(); } void BackgroundWorkerDemo() { /* * WorkerSupportsCancellation - 是否支持在其他线程中取消该线程的操作 * WorkerReportsProgress - 是否可以报告操作进度 * ProgressChanged - 报告操作进度时触发的事件 * DoWork - BackgroundWorker 调用 RunWorkerAsync() 方法时触发的事件。在此执行具体操作 * RunWorkerCompleted - 操作完成/取消/出错时触发的事件 */ _backgroundWorker = new System.ComponentModel.BackgroundWorker(); _backgroundWorker.WorkerSupportsCancellation = true; _backgroundWorker.WorkerReportsProgress = true; _backgroundWorker.ProgressChanged += new System.ComponentModel.ProgressChangedEventHandler(_backgroundWorker_ProgressChanged); _backgroundWorker.DoWork += new System.ComponentModel.DoWorkEventHandler(_backgroundWorker_DoWork); _backgroundWorker.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted); } private void btnStart_Click(object sender, RoutedEventArgs e) { // IsBusy - 指定的 BackgroundWorker 是否正在后台操作 // RunWorkerAsync(object argument) - 开始在后台线程执行指定的操作 // object argument - 需要传递到 DoWork 的参数 if (!_backgroundWorker.IsBusy) _backgroundWorker.RunWorkerAsync("需要传递的参数"); } private void btnCancel_Click(object sender, RoutedEventArgs e) { // CancelAsync() - 取消 BackgroundWorker 正在执行的后台操作 if (_backgroundWorker.WorkerSupportsCancellation) _backgroundWorker.CancelAsync(); } void _backgroundWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e) { /* * DoWorkEventArgs.Argument - RunWorkerAsync(object argument)传递过来的参数 * DoWorkEventArgs.Cancel - 取消操作 * DoWorkEventArgs.Result - 操作的结果。将传递到 RunWorkerCompleted 所指定的方法 * BackgroundWorker.ReportProgress(int percentProgress, object userState) - 向 ProgressChanged 汇报操作的完成进度 * int percentProgress - 操作完成的百分比 1% - 100% * object userState - 传递到 ProgressChanged 的参数 */ for (int i = 0; i < 10; i++) { if ((_backgroundWorker.CancellationPending == true)) { e.Cancel = true; break; } else { System.Threading.Thread.Sleep(1000); _backgroundWorker.ReportProgress((i + 1) * 10, i); } } e.Result = "操作已完成"; } void _backgroundWorker_ProgressChanged(object sender, System.ComponentModel.ProgressChangedEventArgs e) { // ProgressChangedEventArgs.ProgressPercentage - ReportProgress 传递过来的操作完成的百分比 // ProgressChangedEventArgs.UserState - ReportProgress 传递过来的参数 txtProgress.Text = string.Format("完成进度:{0}%;参数:{1}", e.ProgressPercentage, e.UserState); } void _backgroundWorker_RunWorkerCompleted(object sender, System.ComponentModel.RunWorkerCompletedEventArgs e) { /* * RunWorkerCompletedEventArgs.Error - DoWork 时产生的错误 * RunWorkerCompletedEventArgs.Cancelled - 后台操作是否已被取消 * RunWorkerCompletedEventArgs.Result - DoWork 的结果 */ if (e.Error != null) { txtMsg.Text += e.Error.ToString() + "/r/n"; } else if (e.Cancelled) { txtMsg.Text += "操作被取消/r/n"; } else { txtMsg.Text += e.Result.ToString() + "/r/n"; } } } }


4、ThreadPool.xaml

<UserControl x:Class="Silverlight20.Thread.ThreadPool" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <StackPanel HorizontalAlignment="Left" Margin="5"> <TextBlock x:Name="txtMsgQueueUserWorkItem" Text="click here" MouseLeftButtonDown="txtMsgQueueUserWorkItem_MouseLeftButtonDown" Margin="30" /> <TextBlock x:Name="txtRegisterWaitForSingleObject" Text="click here" MouseLeftButtonDown="txtRegisterWaitForSingleObject_MouseLeftButtonDown" Margin="30" /> </StackPanel> </UserControl>

ThreadPool.xaml.cs

using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Shapes; namespace Silverlight20.Thread { public partial class ThreadPool : UserControl { public ThreadPool() { InitializeComponent(); } private void txtMsgQueueUserWorkItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { // ThreadPool - 线程池的管理类 // QueueUserWorkItem(WaitCallback callBack, Object state) - 将指定方法加入线程池队列 // WaitCallback callBack - 需要在新开线程里执行的方法 // Object state - 传递给指定方法的参数 System.Threading.ThreadPool.QueueUserWorkItem(DoWork, DateTime.Now); } private void DoWork(object state) { // 作为线程管理策略的一部分,线程池在创建线程前会有一定的延迟 // 也就是说线程入队列的时间和线程启动的时间之间有一定的间隔 DateTime dtJoin = (DateTime)state; DateTime dtStart = DateTime.Now; System.Threading.Thread.Sleep(3000); DateTime dtEnd = DateTime.Now; // Dispatcher.BeginInvoke() - 在与 Dispatcher 相关联的线程上执行指定的操作。自动线程同步 this.Dispatcher.BeginInvoke(() => { txtMsgQueueUserWorkItem.Text += string.Format("/r/n入队列时间{0} 启动时间{1} 完成时间{2}", dtJoin.ToString(), dtStart.ToString(), dtEnd.ToString()); }); } private void txtRegisterWaitForSingleObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) { System.Threading.AutoResetEvent done = new System.Threading.AutoResetEvent(false); // 为了传递 RegisteredWaitHandle 对象,要将其做一个封装 RegisteredWaitHandlePacket packet = new RegisteredWaitHandlePacket(); // RegisterWaitForSingleObject - 注册一个 WaitHandle 。在超时或发信号的情况下对指定的回调方法做调用 // 第一个参数:需要注册的 WaitHandle // 第二个参数:需要回调的方法(此处省略掉了委托类型) // 第三个参数:传递给回调方法的参数 // 第四个参数:超时时间(到超时时间则调用指定的方法) // 第五个参数:是否为一次调用(是到超时时间一次性调用指定的方法,还是每次超时时间后都调用指定的方法) packet.Handle = System.Threading.ThreadPool.RegisterWaitForSingleObject ( done, WaitOrTimer, packet, 100, false ); System.Threading.Thread.Sleep(555); done.Set(); // 发出信号,调用 RegisterWaitForSingleObject 所指定的方法 } public void WaitOrTimer(object state, bool timedOut) { RegisteredWaitHandlePacket packet = state as RegisteredWaitHandlePacket; // bool timedOut - 是否是因为超时而执行到这里 if (!timedOut){ // 如果不是因为超时而执行到这里(即因为 AutoResetEvent 发出了信号而执行到这里),则注销指定的 RegisteredWaitHandle packet.Handle.Unregister(null); } this.Dispatcher.BeginInvoke(() => { txtRegisterWaitForSingleObject.Text += String.Format("/r/n是否收到信号:{0}", (!timedOut).ToString()); }); } } /// <summary> /// 封装了 RegisteredWaitHandle 的类 /// </summary> public class RegisteredWaitHandlePacket { public System.Threading.RegisteredWaitHandle Handle { get; set; } } }


OK[源码下载]


最新文章

123

最新摄影

微信扫一扫

第七城市微信公众平台