zoukankan      html  css  js  c++  java
  • 2.0线程之Thread, Timer, BackgroundWorker, ThreadPool

    介绍
    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; }
        }

    }


  • 相关阅读:
    UVa 1354 天平难题 (枚举二叉树)
    广西邀请赛总结
    UVa 12118 检查员的难题 (dfs判连通, 构造欧拉通路)
    UVA
    Uva 127 "Accordian" Patience (模拟)
    UVA 10539 Almost Prime Numbers( 素数因子)
    HDU 1272 小希的迷宫(并查集)
    HDU 1213 How Many Tables (并查集)
    POJ 2236 Wireless Network(并查集)
    HDU 1233 还是畅通工程 ( Kruskal或Prim)
  • 原文地址:https://www.cnblogs.com/bingyun84/p/1499172.html
Copyright © 2011-2022 走看看