多線程之其他輔助類: SpinWait, SpinLock, Volatile, SynchronizationContext, CoreDispatcher, ThreadLocal, ThreadStaticAttribute
介紹
重新想象 Windows 8 Store Apps 之 多線程操作的其 他輔助類
SpinWait - 自旋等待
SpinLock - 自旋鎖
volatile - 必在記憶體
SynchronizationContext - 在指定的線程上同步數 據
CoreDispatcher - 調度器,用於線程同步
ThreadLocal - 用於儲存每 個線程自己的資料
ThreadStaticAttribute - 所指定的靜態變數對每個線程都是唯一的
樣本
1、示範 SpinWait 的使用
Thread/Other/SpinWaitDemo.xaml.cs
/* * SpinWait - 自旋等待,一個低層級的同步類型。它不會放棄任何 cpu 時間,而是讓 cpu 不停的迴圈等待 * * 適用情境:多核 cpu ,預期等待時間非常短(幾微秒) * 本例只是用於描述 SpinWait 的用法,而不代表適用情境 */ using System;using System.Threading;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation; namespace XamlDemo.Thread.Other{ public sealed partial class SpinWaitDemo : Page { public SpinWaitDemo() { this.InitializeComponent(); } protected override void OnNavigatedTo(NavigationEventArgs e) { lblMsg.Text = DateTime.Now.ToString("mm:ss.fff"); SpinWait.SpinUntil( () => // 以下條件成立時,結束等待 { return false; } // 如果此逾時時間過後指定的條件還未成立,則強制結束等待 ,1000); lblMsg.Text += Environment.NewLine; lblMsg.Text += DateTime.Now.ToString("mm:ss.fff"); SpinWait.SpinUntil( () => // 以下條件成立時,結束等待 { return DateTime.Now.Second % 2 == 0; }); lblMsg.Text += Environment.NewLine; lblMsg.Text += DateTime.Now.ToString("mm:ss.fff"); } }}
2、示範 SpinLock 的使用
Thread/Other/SpinLockDemo.xaml.cs
/* * SpinLock - 自旋鎖,一個低層級的互斥鎖。它不會放棄任何 cpu 時間,而是讓 cpu 不停的迴圈等待,直至鎖變為可用為止 * * 適用情境:多核 cpu ,預期等待時間非常短(幾微秒) * 本例只是用於描述 SpinLock 的用法,而不代表適用情境 */ using System.Collections.Generic;using System.Threading;using System.Threading.Tasks;using Windows.UI.Xaml.Controls;using Windows.UI.Xaml.Navigation; namespace XamlDemo.Thread.Other{ public sealed partial class SpinLockDemo : Page { private static int _count; public SpinLockDemo() { this.InitializeComponent(); } protected async override void OnNavigatedTo(NavigationEventArgs e) { SpinLock spinLock = new SpinLock(); List<Task> tasks = new List<Task>(); // 一共 100 個任務並存執行,每個任務均累加同一個靜態變數 100000 次,以類比並發訪問靜態變數的情境 for (int i = 0; i < 100; i++) { Task task = Task.Run( () => { bool lockTaken = false; try { // IsHeld - 鎖當前是否已由任何線程佔用 // IsHeldByCurrentThread - 鎖是否由當前線程佔用 // 要擷取 IsHeldByCurrentThread 屬性,則IsThreadOwnerTrackingEnabled 必須為 true,可以在建構函式中指定,預設就是 true // 進入鎖,lockTaken - 是否已擷取到鎖 spinLock.Enter(ref lockTaken); for (int j = 0; j < 100000; j++) { _count++; } } finally { // 釋放鎖 if (lockTaken) spinLock.Exit(); } }); tasks.Add(task); } // 等待所有任務執行完畢 await Task.WhenAll(tasks); lblMsg.Text = "count: " + _count.ToString(); } }}