多線程之線程池: 延遲執行, 周期執行, 在線程池中找一個線程去執行指定的方法
介紹
重新想象 Windows 8 Store Apps 之 線程池
通過 ThreadPoolTimer 實現延遲執行
通過 ThreadPoolTimer 實現周期執行
通過 ThreadPool 實現“在線程池中找一個線程去執行指定的方 法”
示例
1、通過 ThreadPoolTimer 實現延遲執行(ThreadPoolTimer 在 Windows.System.Threading 命名空間下)
Thread/ThreadPool/DelayTimer.xaml
<Page x:Class="XamlDemo.Thread.ThreadPool.DelayTimer" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Thread.ThreadPool" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> <Button Name="btnCreateDelay" Content="延遲 3 秒後執行一個任務" Click="btnCreateDelay_Click_1" Margin="0 10 0 0" /> <Button Name="btnCancelDelay" Content="取消任務" Click="btnCancelDelay_Click_1" Margin="0 10 0 0" /> </StackPanel> </Grid> </Page>
Thread/ThreadPool/DelayTimer.xaml.cs
/* * 通過 ThreadPoolTimer 實現延遲執行(ThreadPoolTimer 在 Windows.System.Threading 命名空間下) * * ThreadPoolTimer - 計時器 * ThreadPoolTimer CreateTimer(TimerElapsedHandler handler, TimeSpan delay, TimerDestroyedHandler destroyed); - 創建一個用於延遲執行的計時器 * handler - 指定的延遲時間過後,所需要執行的方法 * delay - 延遲時間 * destroyed - 當 ThreadPoolTimer 完成了自身的使命後所執行的方法(比如延遲方法執行完了或計時器被取消了) * Cancel() - 取消計時器 * Delay - 延遲時間,只讀 */ using System; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.System.Threading; using Windows.UI.Core; namespace XamlDemo.Thread.ThreadPool { public sealed partial class DelayTimer : Page { private ThreadPoolTimer _timer; public DelayTimer() { this.InitializeComponent(); } // 創建一個延遲計時器 private void btnCreateDelay_Click_1(object sender, RoutedEventArgs e) { _timer = ThreadPoolTimer.CreateTimer( (timer) => { var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { lblMsg.Text = "任務執行了"; }); }, TimeSpan.FromSeconds(3), (timer) => { var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { lblMsg.Text += Environment.NewLine; lblMsg.Text += "ThreadPoolTimer 的使命結束了"; }); }); lblMsg.Text = "延遲 3 秒後執行一個任務"; } // 取消計時器 private void btnCancelDelay_Click_1(object sender, RoutedEventArgs e) { if (_timer != null) { _timer.Cancel(); _timer = null; lblMsg.Text += Environment.NewLine; lblMsg.Text += "任務取消了"; } } } }
2、通過 ThreadPoolTimer 實現周期執行(ThreadPoolTimer 在 Windows.System.Threading 命名 空間下)
Thread/ThreadPool/PeriodicTimer.xaml
<Page x:Class="XamlDemo.Thread.ThreadPool.PeriodicTimer" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Thread.ThreadPool" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> <Button Name="btnCreatePeriodic" Content="執行一個周期任務" Click="btnCreatePeriodic_Click_1" Margin="0 10 0 0" /> <Button Name="btnCancelPeriodic" Content="取消任務" Click="btnCancelPeriodic_Click_1" Margin="0 10 0 0" /> </StackPanel> </Grid> </Page>
Thread/ThreadPool/PeriodicTimer.xaml.cs
/* * 通過 ThreadPoolTimer 實現周期執行(ThreadPoolTimer 在 Windows.System.Threading 命名空間下) * * ThreadPoolTimer - 計時器 * ThreadPoolTimer CreatePeriodicTimer(TimerElapsedHandler handler, TimeSpan period, TimerDestroyedHandler destroyed) - 創建一個用於延遲執行的計時器 * handler - 每個周期時間點到達之後,所需要執行的方法 * period - 周期執行的間隔時間 * destroyed - 當 ThreadPoolTimer 完成了自身的使命後所執行的方法(比如計時器被取消了) * Cancel() - 取消計時器 * Period - 間隔時間,只讀 */ using System; using Windows.System.Threading; using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace XamlDemo.Thread.ThreadPool { public sealed partial class PeriodicTimer : Page { private ThreadPoolTimer _timer; private int _periodicTimerCount = 0; public PeriodicTimer() { this.InitializeComponent(); } // 創建一個周期計時器 private void btnCreatePeriodic_Click_1(object sender, RoutedEventArgs e) { _timer = ThreadPoolTimer.CreatePeriodicTimer( (timer) => { _periodicTimerCount++; var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { lblMsg.Text = "任務執行次數:" + _periodicTimerCount.ToString(); }); }, // 第 1 次執行 handler 是在計時器被創建的 100 毫秒之後,然後每 100 毫秒執行一次 handler // 計時器會保證每 100 毫秒調用一次 handler,而不管上一次 handler 是否已執行完 TimeSpan.FromMilliseconds(100), (timer) => { var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { lblMsg.Text += Environment.NewLine; lblMsg.Text += "ThreadPoolTimer 的使命結束了"; }); }); lblMsg.Text = "任務執行次數:0"; } // 取消計時器 private void btnCancelPeriodic_Click_1(object sender, RoutedEventArgs e) { if (_timer != null) { _timer.Cancel(); _timer = null; _periodicTimerCount = 0; lblMsg.Text = "任務取消了"; } } } }
3、通過 ThreadPool 實現“在線程池中找一個線程去執行指定的方法”(ThreadPool 在 Windows.System.Threading 命名空間下)
Thread/ThreadPool/WorkItem.xaml
<Page x:Class="XamlDemo.Thread.ThreadPool.WorkItem" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:XamlDemo.Thread.ThreadPool" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid Background="Transparent"> <StackPanel Margin="120 0 0 0"> <TextBlock Name="lblMsg" FontSize="14.667" /> <TextBlock Name="lblProgress" FontSize="14.667" /> <Button Name="btnCreateWorkItem" Content="在線程池中找一個線程去執行指定的方法" Click="btnCreateWorkItem_Click_1" Margin="0 10 0 0" /> <Button Name="btnCancelWorkItem" Content="取消任務" Click="btnCancelWorkItem_Click_1" Margin="0 10 0 0" /> <Button Name="btnCreateWorkItemByAwait" Content="通過 async await 簡化“在線程池中找一個線程去執行指定的方法”" Click="btnCreateWorkItemByAwait_Click_1" Margin="0 30 0 0" /> </StackPanel> </Grid> </Page>
Thread/ThreadPool/WorkItem.xaml.cs
/* * 通過 ThreadPool 實現“在線程池中找一個線程去執行指定的方法”(ThreadPool 在Windows.System.Threading 命名空間下) * * ThreadPool - 線程池 * IAsyncAction RunAsync(WorkItemHandler handler, WorkItemPriority priority) - 在線程池中找一個線程去執行指定的方法,並指定其優先級 * handler - 需要調用的方法 * priority - 優先級(Windows.UI.Core.CoreDispatcherPriority 枚舉:Low, Normal, High) * * * 注:關於 IAsyncAction 請參見 XamlDemo/Thread/Async 中的說明 */ using System; using System.Threading; using Windows.Foundation; using Windows.System.Threading; using Windows.UI.Core; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; namespace XamlDemo.Thread.ThreadPool { public sealed partial class WorkItem : Page { private IAsyncAction _threadPoolWorkItem; private ManualResetEvent _sleep = new ManualResetEvent(false); public WorkItem() { this.InitializeComponent(); } // 在線程池中找一個線程去執行指定的方法,並指定其優先級 private void btnCreateWorkItem_Click_1(object sender, RoutedEventArgs e) { _threadPoolWorkItem = Windows.System.Threading.ThreadPool.RunAsync( (threadPoolWorkItem) => { int percent = 0; // 用於模擬執行進度(0 - 100) while (percent < 100) { // 當前線程 sleep 100 毫秒 _sleep.WaitOne(100); // 如果 IAsyncAction 被取消了則退出此 handler 的執行 if (threadPoolWorkItem.Status == AsyncStatus.Canceled) break; percent++; var ignored = Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { lblProgress.Text = "進度:" + percent.ToString() + "%"; }); } }, WorkItemPriority.High); // IAsyncAction 完成之後(比如任務完成了或者任務取消了) // 關於 IAsyncAction 的詳細說明請參見 XamlDemo/Thread/Async _threadPoolWorkItem.Completed = new AsyncActionCompletedHandler( async (IAsyncAction threadPoolWorkItem, AsyncStatus status) => { await Dispatcher.RunAsync(CoreDispatcherPriority.High, () => { switch (status) { case AsyncStatus.Completed: lblMsg.Text = "任務完成了"; break; case AsyncStatus.Canceled: lblMsg.Text = "任務取消了"; break; case AsyncStatus.Started: case AsyncStatus.Error: break; } }); }); lblProgress.Text = "進度:0%"; lblMsg.Text = "任務開始了"; } // 取消任務 private void btnCancelWorkItem_Click_1(object sender, RoutedEventArgs e) { if (_threadPoolWorkItem != null) { _threadPoolWorkItem.Cancel(); _threadPoolWorkItem = null; } } // 通過 async await 簡化 ThreadPool.RunAsync() 的使用(關於 async 和 await 的詳細說明請參見 XamlDemo/Thread/Async) private async void btnCreateWorkItemByAwait_Click_1(object sender, RoutedEventArgs e) { lblProgress.Text = ""; lblMsg.Text = ""; string result = ""; await Windows.System.Threading.ThreadPool.RunAsync( delegate { new ManualResetEvent(false).WaitOne(3000); result = "在線程池中找一個線程去執行指定的邏輯,然後通過 await 返回 UI 線程"; }); lblMsg.Text = result; } } }
OK
[源碼下載]:http://files.cnblogs.com/webabcd/Windows8.rar