重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法
作者:webabcd
介绍
重新想象 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
[源码下载]