zoukankan      html  css  js  c++  java
  • 稳扎稳打Silverlight(25) 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool

    [索引页]
    [源码下载]


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


    作者:webabcd


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


    在线DEMO
    http://www.cnblogs.com/webabcd/archive/2008/10/09/1307486.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"30001000);
            }


            
    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(
    5000500); // 执行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 getset; }
        }

    }



    OK
    [源码下载]
  • 相关阅读:
    研究table-cell和overflow
    自己封装jquery的一些方法 链式调用模式
    简单的抖动运动 主要利用offset left 和 setTimeout
    闭包的讲解与简单实用(重新理解)
    操作iframe 的方法与兼容性
    360度全景图片
    数组排序
    怎么让链式调用setTimeout停止
    setInterval 和 setTimeout
    重力碰撞运动的疑惑
  • 原文地址:https://www.cnblogs.com/webabcd/p/1361935.html
Copyright © 2011-2022 走看看