backgroundworker:Silverlight(25) - 2.0线程的Thread Timer BackgroundWorker ThreadPool

  本文源代码下载地址:

  http://flashview.ddvip.com/2008_12/Silverlight.rar

  介绍

  Silverlight 2.0使用Thread, Timer, BackgroundWorker, ThreadPool来实现多线程开发

  Thread - 用于线程创建和控制

  Timer - 用于以指定时间间隔执行指定思路方法

  BackgroundWorker - 用于在单独线程上运行操作

  ThreadPool - 线程池管理类

  举例

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


  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 ;
using .Collections.Generic;
using .Linq;
using .Net;
using .Windows;
using .Windows.Controls;
using .Windows.Documents;
using .Windows.Input;
using .Windows.Media;
using .Windows.Media.Animation;
using .Windows.Shapes;
Silverlight20.Thread
{
  public partial Timer : UserControl
  {
    .Threading.SynchronizationContext _syncContext;
    // Timer - 用于以指定时间间隔执行指定思路方法
    .Threading.Timer _timer;
    private _flag = 0;
    public Timer
    {
      InitializeComponent;
      // UI 线程
      _syncContext = .Threading.SynchronizationContext.Current;
      Demo;
    }
    void Demo
    {
      // 输出当前时间
      txtMsg.Text = DateTime.Now. + "rn";
      // 第个参数:定时器需要思路方法
      // 第 2个参数:传给需要思路方法参数
      // 第 3个参数:此时间后启动定时器
      // 第 4个参数:指定思路方法间隔时间(.Threading.Timeout.Infinite 为无穷大)
      _timer = .Threading.Timer(MyTimerCallback, "webabcd", 3000, 1000);
    }
    private void MyTimerCallback(object state)
    {
       result = .Format("{0} - {1}rn", DateTime.Now., ()state);
      // UI 线程不会做自动线程同步
      _syncContext.Post(delegate { txtMsg.Text result; }, null);
      _flag;
       (_flag 5)
        _timer.Change(5000, 500); // 执行5次后计时器重置为5秒后启动每5毫秒间隔时间执行次指定思路方法
       (_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 ;
using .Collections.Generic;
using .Linq;
using .Net;
using .Windows;
using .Windows.Controls;
using .Windows.Documents;
using .Windows.Input;
using .Windows.Media;
using .Windows.Media.Animation;
using .Windows.Shapes;
Silverlight20.Thread
{
  public partial BackgroundWorker : UserControl
  {
    // BackgroundWorker - 用于在单独线程上运行操作例如可以在非UI线程上运行耗时操作以避免UI停止响应
    .ComponentModel.BackgroundWorker _backgroundWorker;
    public BackgroundWorker
    {
      InitializeComponent;
      BackgroundWorkerDemo;
    }
    void BackgroundWorkerDemo
    {
      /**//*
       * WorkerSupportsCancellation - 是否支持在其他线程中取消该线程操作
       * WorkerReportsProgress - 是否可以报告操作进度
       * ProgressChanged - 报告操作进度时触发事件
       * DoWork - BackgroundWorker RunWorkerAsync 思路方法时触发事件在此执行具体操作
       * RunWorkerCompleted - 操作完成/取消/出错时触发事件
       */
      _backgroundWorker = .ComponentModel.BackgroundWorker;
      _backgroundWorker.WorkerSupportsCancellation = true;
      _backgroundWorker.WorkerReportsProgress = true;
      _backgroundWorker.ProgressChanged .ComponentModel.ProgressChangedEventHandler(_backgroundWorker_ProgressChanged);
      _backgroundWorker.DoWork .ComponentModel.DoWorkEventHandler(_backgroundWorker_DoWork);
      _backgroundWorker.RunWorkerCompleted .ComponentModel.RunWorkerCompletedEventHandler(_backgroundWorker_RunWorkerCompleted);
    }
    private void btnStart_Click(object sender, RoutedEventArgs e)
    {
      // IsBusy - 指定 BackgroundWorker 是否正在后台操作
      // RunWorkerAsync(object argument) - 开始在后台线程执行指定操作
      //   object argument - 需要传递到 DoWork 参数
       (!_backgroundWorker.IsBusy)
        _backgroundWorker.RunWorkerAsync("需要传递参数");
    }
    private void btnCancel_Click(object sender, RoutedEventArgs e)
    {
      // CancelAsync - 取消 BackgroundWorker 正在执行后台操作
       (_backgroundWorker.WorkerSupportsCancellation)
        _backgroundWorker.CancelAsync;
    }
    void _backgroundWorker_DoWork(object sender, .ComponentModel.DoWorkEventArgs e)
    {
      /**//*
       * DoWorkEventArgs.Argument - RunWorkerAsync(object argument)传递过来参数
       * DoWorkEventArgs.Cancel - 取消操作
       * DoWorkEventArgs.Result - 操作结果将传递到 RunWorkerCompleted 所指定思路方法
       * BackgroundWorker.ReportProgress( percentProgress, object userState) - 向 ProgressChanged 汇报操作完成进度
       *   percentProgress - 操作完成百分比 1% - 100%
       *   object userState - 传递到 ProgressChanged 参数
       */
      for ( i = 0; i < 10; i)
      {
         ((_backgroundWorker.CancellationPending true))
        {
          e.Cancel = true;
          ;
        }
        
        {
          .Threading.Thread.Sleep(1000);
          _backgroundWorker.ReportProgress((i + 1) * 10, i);
        }
      }
      e.Result = "操作已完成";
    }
    void _backgroundWorker_ProgressChanged(object sender, .ComponentModel.ProgressChangedEventArgs e)
    {
      // ProgressChangedEventArgs.ProgressPercentage - ReportProgress 传递过来操作完成百分比
      // ProgressChangedEventArgs.UserState - ReportProgress 传递过来参数
      txtProgress.Text = .Format("完成进度:{0}%;参数:{1}",
        e.ProgressPercentage,
        e.UserState);
    }
    void _backgroundWorker_RunWorkerCompleted(object sender, .ComponentModel.RunWorkerCompletedEventArgs e)
    {
      /**//*
       * RunWorkerCompletedEventArgs.Error - DoWork 时产生
       * RunWorkerCompletedEventArgs.Cancelled - 后台操作是否已被取消
       * RunWorkerCompletedEventArgs.Result - DoWork 结果
       */
       (e.Error != null)
      {
        txtMsg.Text e.Error. + "rn";
      }
       (e.Cancelled)
      {
        txtMsg.Text "操作被取消rn";
      }
      
      {
        txtMsg.Text e.Result. + "rn";
      }
    }
  }
}


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


Tags:  silverlight.2.0 silverlight是什么 silverlight backgroundworker

延伸阅读

最新评论

发表评论