微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

[索引页]
[源码下载]


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


作者:webabcd


介绍
Silverlight 2.0 使用Thread,ThreadPool来实现多线程开发
    Thread - 用于线程的创建和控制的类
    Timer - 用于以指定的时间间隔执行指定的方法的类
    BackgroundWorker - 用于在单独的线程上运行操作
    ThreadPool - 线程池的管理类


在线DEMO
http://www.voidcn.com/article/p-ounmxjds-tq.html


示例
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; }

        }

}
 
 

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

相关推荐