silverlight:Silverlight(26) - 2.0线程的Lock Interlocked EventWaitHandle Monitor ThreadStaticAttribu

  本文源代码下载地址:

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

  介绍

  Silverlight 2.0使用Lock, Interlocked, EventWaitHandle, Monitor来实现线程同步

  Lock - 确保代码块完成运行而不会被其他线程中断

  Interlocked - 为多个线程共享变量提供原子级操作

  EventWaitHandle - 通知其他线程是否可入

  Monitor - 提供同步访问对象机制

  ThreadStaticAttribute - 所指定静态变量对每个线程都是唯

  举例

  1、Lock.xaml

<UserControl x:Class="Silverlight20.Thread.Lock"
  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>


  Lock.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 Lock : UserControl
  {
    // 需要被 lock 静态变量
    private readonly object objLock = object;
    private i;
    public Lock
    {
      InitializeComponent;
      i = 0;
      for ( x = 0; x < 100; x)
      {
        // 开 100 个线程去操作静态变量 i
        .Threading.Thread thread = .Threading.Thread( .Threading.ThreadStart(DoWork));
        thread.Start;
      }
      .Threading.Thread.Sleep(3000);
      // 3 秒后 100 个线程都应该执行完毕了取得 i 结果
      // 做了并发处理结果为 100 去掉 lock 可得到不做并发处理结果
      txtMsg.Text = i.;
    }
    private void DoWork
    {
      try
      {
        // lock - 确保代码块完成运行而不会被其他线程中断其参数必须为个引用类型对象
        lock (objLock)
        {
           j = i + 1;
          // 模拟多线程并发操作静态变量 i 情况
          .Threading.Thread.Sleep(10);
          i = j;
        }
      }
      finally
      {
        // code
      }
    }
  }
}


  2、Interlocked.xaml

<UserControl x:Class="Silverlight20.Thread.Interlocked"
  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>


  Interlocked.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 Interlocked : UserControl
  {
    private i;
    public Interlocked
    {
      InitializeComponent;
      i = 0;
      for ( x = 0; x < 100; x)
      {
        // 开 100 个线程去操作静态变量 i
        .Threading.Thread thread = .Threading.Thread( .Threading.ThreadStart(DoWork));
        thread.Start;
      }
      .Threading.Thread.Sleep(1000);
      // 1 秒后 100 个线程都应该执行完毕了取得 i 结果
      txtMsg.Text = i.;
    }
    private void DoWork
    {
      try
      {
        // Interlocked - 为多个线程共享变量提供原子级操作(避免并发问题)
        // i 加 1
        .Threading.Interlocked.Increment(ref i);
        // i 减 1
        .Threading.Interlocked.Decrement(ref i);
        // i 加 1
        .Threading.Interlocked.Add(ref i, 1);
        // 如果 i 等于 100 则将 i 赋值为 101
        .Threading.Interlocked.CompareExchange(ref i, 101, 100);
        // 将 i 赋值为 1000
        // .Threading.Interlocked.Exchange(ref i, 1000);
      }
      finally
      {
        // code
      }
    }
  }
}


  3、EventWaitHandle.xaml

<UserControl x:Class="Silverlight20.Thread.EventWaitHandle"
  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="txtAutoReEvent" />
    <TextBlock x:Name="txtManualReEvent" />
  </StackPanel>
</UserControl>


  EventWaitHandle.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 EventWaitHandle : UserControl
  {
    // AutoReEvent(bool state) - 通知其他线程是否可入自动 Re
    //   bool state - 是否为终止状态即是否禁止其他线程入内
    private .Threading.AutoReEvent autoReEvent =
       .Threading.AutoReEvent(false);
    // ManualReEvent(bool state) - 通知其他线程是否可入手动 Re
    //   bool state - 是否为终止状态即是否禁止其他线程入内
    private .Threading.ManualReEvent manualReEvent =
       .Threading.ManualReEvent(false);
    private i;
    public EventWaitHandle
    {
      InitializeComponent;
      // 演示 AutoReEvent
      AutoReEventDemo;
      // 演示 ManualReEvent
      ManualReEventDemo;
    }
    private void AutoReEventDemo
    {
      i = 0;
      for ( x = 0; x < 100; x)
      {
        // 开 100 个线程去操作静态变量 i
        .Threading.Thread thread =
           .Threading.Thread( .Threading.ThreadStart(AutoReEventDemoCallback));
        thread.Start;
        // 阻塞当前线程直到 AutoReEvent 发出 Set 信号
        autoReEvent.WaitOne;
      }
      .Threading.Thread.Sleep(1000);
      // 1 秒后 100 个线程都应该执行完毕了取得 i 结果
      txtAutoReEvent.Text = i.;
    }
    private void AutoReEventDemoCallback
    {
      try
      {
         j = i + 1;
        // 模拟多线程并发操作静态变量 i 情况
        .Threading.Thread.Sleep(5);
        i = j;
      }
      finally
      {
        // 发出 Set 信号以释放 AutoReEvent 所阻塞线程
        autoReEvent.Set;
      }
    }
    private void ManualReEventDemo
    {
      i = 0;
      for ( x = 0; x < 100; x)
      {
        // Re - 将 ManualReEvent 变为非终止状态即由此线程控制 ManualReEvent
        //   其他线程排队直到 ManualReEvent 发出 Set 信号(AutoReEvent 在 Set 时会自动 Re)
        manualReEvent.Re;
        // 开 100 个线程去操作静态变量 i
        .Threading.Thread thread =
           .Threading.Thread( .Threading.ThreadStart(ManualReEventDemoCallback));
        thread.Start;
        // 阻塞当前线程直到 ManualReEvent 发出 Set 信号
        manualReEvent.WaitOne;
      }
      .Threading.Thread.Sleep(1000);
      // 1 秒后 100 个线程都应该执行完毕了取得 i 结果
      txtManualReEvent.Text = i.;
    }
    private void ManualReEventDemoCallback
    {
      try
      {
         j = i + 1;
        // 模拟多线程并发操作静态变量 i 情况
        .Threading.Thread.Sleep(5);
        i = j;
      }
      finally
      {
        // 发出 Set 信号以释放 ManualReEvent 所阻塞线程同时 ManualReEvent 变为终止状态)
        manualReEvent.Set;
      }
    }
  }
}


  4、Monitor.xaml

<UserControl x:Class="Silverlight20.Thread.Monitor"
  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>


  Monitor.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 Monitor : UserControl
  {
    private readonly object objLock = object;
    private i;
    public Monitor
    {
      InitializeComponent;
      i = 0;
      for ( x = 0; x < 100; x)
      {
        // 开 100 个线程去操作静态变量 i
        .Threading.Thread thread = .Threading.Thread( .Threading.ThreadStart(DoWork));
        thread.Start;
      }
      .Threading.Thread.Sleep(1000);
      // 1 秒后 100 个线程都应该执行完毕了取得 i 结果
      txtMsg.Text = i.;
    }
    private void DoWork
    {
      try
      {
        // Monitor - 提供同步访问对象机制
        // Enter - 在指定对象上获取排他锁
        .Threading.Monitor.Enter(objLock);
         j = i + 1;
        // 模拟多线程并发操作静态变量 i 情况
        .Threading.Thread.Sleep(5);
        i = j;
        // Exit - 释放指定对象上排他锁
        .Threading.Monitor.Exit(objLock);
      }
      finally
      {
        // code
      }
    }
  }
}


  5、ThreadStaticAttribute.xaml

<UserControl x:Class="Silverlight20.Thread.ThreadStaticAttribute"
  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" />
    <TextBlock x:Name="txtMsg2" />
  </StackPanel>
</UserControl>


  ThreadStaticAttribute.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 ThreadStaticAttribute : UserControl
  {
    // ThreadStatic - 所指定静态变量对每个线程都是唯
    [.ThreadStatic]
    private value;
    // 静态变量对每个线程都是共用
    private value2;
    public ThreadStaticAttribute
    {
      InitializeComponent;
      Demo;
    }
    void Demo
    {
      .Threading.Thread thread = .Threading.Thread(DoWork);
      thread.Name = "线程1";
      thread.Start;
      .Threading.Thread.Sleep(100);
      .Threading.Thread thread2 = .Threading.Thread(DoWork2);
      thread2.Name = "线程2";
      thread2.Start;
    }
    void DoWork
    {
      for ( i = 0; i < 10; i)
      {
        // 线程1对静态变量操作
        value;
        value2;
      }
       s = value.; // value - 本线程独有静态变量
       s2 = value2.; // value2 - 所有线程共用静态变量
      this.Dispatcher.BeginInvoke(delegate { txtMsg.Text = s + " - " + s2; });
      // this.Dispatcher.BeginInvoke(delegate { txtMsg.Text = value + " - " + value2; }); // 在UI线程上所以value值为UI线程上value值即 0
    }
    void DoWork2
    {
      for ( i = 0; i < 10; i)
      {
        // 线程2对静态变量操作
        value;
        value2;
      }
       s = value.; // value - 本线程独有静态变量
       s2 = value2.; // value2 - 所有线程共用静态变量
      this.Dispatcher.BeginInvoke(delegate { txtMsg2.Text = s + " - " + s2; });
      // this.Dispatcher.BeginInvoke(delegate { txtMsg2.Text = value + " - " + value2; }); // 在UI线程上所以value值为UI线程上value值即 0
    }
  }
}


Tags:  silverlight2 silverlight.2.0 silverlight是什么 silverlight

延伸阅读

最新评论

发表评论