32、ThreadPool
namespace Windows.System.Threading { // 表示通过 CreateTimer 或 CreatePeriodicTimer 创建的计时器。 public sealed class ThreadPoolTimer { //获取通过 CreateTimer 创建的单用途计时器的超时值。 // 返回结果: 超时值(以毫秒为单位)。超过超时值时,计时器过期, //并调用其 TimerElapsedHandler 委托。 public TimeSpan Delay { get; } // 获取通过 CreatePeriodicTimer 创建的周期计时器的超时值。 // 返回结果: 超时值(以毫秒为单位)。超过超时值时,计时器过期,调用其 TimerElapsedHandler 委托, //计时器重新激活。继续此行为,直到计时器被取消。 public TimeSpan Period { get; } // 取消计时器。 public void Cancel(); public static ThreadPoolTimer CreatePeriodicTimer(TimerElapsedHandler handler, TimeSpan period); public static ThreadPoolTimer CreatePeriodicTimer(TimerElapsedHandler handler,
TimeSpan period, TimerDestroyedHandler destroyed); public static ThreadPoolTimer CreateTimer(TimerElapsedHandler handler, TimeSpan delay); public static ThreadPoolTimer CreateTimer(TimerElapsedHandler handler,
TimeSpan delay, TimerDestroyedHandler destroyed); } }
namespace Windows.System.Threading { // 表示线程池。 public static class ThreadPool { // 创建工作项。 // handler: 当线程可用于运行工作项时调用的方法。 // 返回结果: 提供对工作项的访问的 IAsyncAction 接口。 public static IAsyncAction RunAsync(WorkItemHandler handler); // 创建工作项并指定其相对于线程池中其他工作项的优先级。 // handler: 当线程可用于运行工作项时调用的方法。 // priority: 该工作项相对于线程池中其他工作项的工作项优先级。此参数的值可以是 Low、Normal 或 High。 // 返回结果: 提供对工作项的访问的 IAsyncAction 接口。 public static IAsyncAction RunAsync(WorkItemHandler handler, WorkItemPriority priority); // 创建工作项,指定其相对于线程池中其他工作项的优先级,并指定工作项的运行时间长度。 // handler: 当线程可用于运行工作项时调用的方法。 // priority: 该工作项相对于线程池中其他工作项的工作项优先级。 // options: 如果此参数是 TimeSliced,则工作项与其他时间片工作项同时运行,时间片工作项的每个工作
//项均接收处理器时间的共享。如果此参数是 None,则工作项在辅助线程变为可用时运行。 // 返回结果: 提供对工作项的访问的 IAsyncAction 接口。 public static IAsyncAction RunAsync(WorkItemHandler handler, WorkItemPriority priority, WorkItemOptions options); } }
下面示例中用到的枚举:
public enum Status { Unregistered = 0, Started = 1, Canceled = 2, Completed = 3 }
1、Thread pool delay timer:
创建一个线程池的 timer 对象,并且在指定的毫秒数后执行相应的方法:
页面截图:
从下拉框中选择 1000 毫秒:
点击 “Create” 按钮,一秒后显示执行结果:
页面的 xaml :
<ComboBox x:Name="DelayMs" SelectedIndex="0"> <ComboBoxItem>0</ComboBoxItem> <ComboBoxItem>100</ComboBoxItem> <ComboBoxItem>500</ComboBoxItem> <ComboBoxItem>1000</ComboBoxItem> <ComboBoxItem>5000</ComboBoxItem> <ComboBoxItem>10000</ComboBoxItem> </ComboBox> <Button x:Name="CreateDelayTimerButton" Content="Create" Click="CreateDelayTimer" IsEnabled="True" /> <Button x:Name="CancelDelayTimerButton" Content="Cancel" Click="CancelDelayTimer" IsEnabled="False" />
显示结果:
<TextBlock x:Name="DelayTimerInfo" /> <TextBlock x:Name="DelayTimerStatus" />
对应的 C# :
页面的变量:
public ThreadPoolTimer DelayTimer; public int DelayTimerMilliseconds = 0; public string DelayTimerInfo = ""; public Status DelayTimerStatus = Status.Unregistered;
点击 “Create” 按钮:
private void CreateDelayTimer(object sender, RoutedEventArgs args) { if (int.TryParse(DelayMs.SelectionBoxItem.ToString(), out DelayTimerMilliseconds)) { DelayTimer = ThreadPoolTimer.CreateTimer( async (timer) => { await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => { UpdateUI(Status.Completed); }); }, TimeSpan.FromMilliseconds(DelayTimerMilliseconds)); UpdateUI(Status.Started); } }
public void UpdateUI(Status status) { DelayTimerInfo.Text = string.Format("Timer delay = {0} ms.", DelayTimerMilliseconds); DelayTimerStatus.Text = status.ToString("g"); bool createButtonEnabled = (status == Status.Started); CreateDelayTimerButton.IsEnabled = !createButtonEnabled; CancelDelayTimerButton.IsEnabled = createButtonEnabled; }
点击 “Cancel” 按钮,timer 取消:
private void CancelDelayTimer(object sender, RoutedEventArgs args) { if (DelayTimer != null) { DelayTimer.Cancel(); UpdateUI(Status.Canceled); } }
2、Thread pool periodic timer :
创建一个线程池 timer 对象,可以以指定的时间循环执行相应的方法,直到这个 timer 被取消。
截图:
选择循环执行的时间为 1 秒:
点击 “Create” 按钮,5 秒中后,调用 5 次方法:
页面的 xaml :
<ComboBox x:Name="PeriodMs" SelectedIndex="0"> <ComboBoxItem>100</ComboBoxItem> <ComboBoxItem>500</ComboBoxItem> <ComboBoxItem>1000</ComboBoxItem> <ComboBoxItem>5000</ComboBoxItem> <ComboBoxItem>10000</ComboBoxItem> </ComboBox> <Button x:Name="CreatePeriodicTimerButton" Content="Create" Click="CreatePeriodicTimer" IsEnabled="True" /> <Button x:Name="CancelPeriodicTimerButton" Content="Cancel" Click="CancelPeriodicTimer" IsEnabled="False" />
<TextBlock x:Name="PeriodicTimerInfo" /> <TextBlock x:Name="PeriodicTimerStatus" />
相应的 C# 页面 :
页面中的参数 :
public ThreadPoolTimer PeriodicTimer; public long PeriodicTimerCount = 0; public int PeriodicTimerMilliseconds = 0; public string PeriodicTimerInfo = ""; public Status PeriodicTimerStatus = Status.Unregistered;
Create 按钮:
private void CreatePeriodicTimer(object sender, RoutedEventArgs args) { if (int.TryParse(PeriodMs.SelectionBoxItem.ToString(), out PeriodicTimerMilliseconds)) { PeriodicTimer = ThreadPoolTimer.CreatePeriodicTimer( async (timer) => { // 以原子操作的形式递增指定变量的值并存储结果。 //方法每调用一次 PeriodicTimerCount 加一 System.Threading.Interlocked.Increment(ref PeriodicTimerCount); await Dispatcher.RunAsync( CoreDispatcherPriority.High, () => { UpdateUI(Status.Completed); }); }, TimeSpan.FromMilliseconds(PeriodicTimerMilliseconds)); UpdateUI(Status.Started); } }
public void UpdateUI(Status status) { switch (status) { case Status.Completed: PeriodicTimerStatus.Text = string.Format("Completion count: {0}", PeriodicTimerCount); break; default: PeriodicTimerStatus.Text = status.ToString("g"); break; } PeriodicTimerInfo.Text = string.Format("Timer Period = {0} ms.", PeriodicTimerMilliseconds); bool createButtonEnabled = ((status != Status.Started) && (status != Status.Completed)); CreatePeriodicTimerButton.IsEnabled = createButtonEnabled; CancelPeriodicTimerButton.IsEnabled = !createButtonEnabled; }
“Cancel” 按钮 :
private void CancelPeriodicTimer(object sender, RoutedEventArgs args) { if (PeriodicTimer != null) { PeriodicTimer.Cancel(); PeriodicTimerCount = 0; UpdateUI(Status.Canceled); } }
3、Thread pool work item:
创建和启动一个线程池工作项并且指定它的优先级。
操作截图:
选择优先级 Hight :
点击 “Create” 按钮,执行过程:
执行结果:
页面的 xaml :
<ComboBox x:Name="Priority" SelectedIndex="0"> <ComboBoxItem>Low</ComboBoxItem> <ComboBoxItem>Normal</ComboBoxItem> <ComboBoxItem>High</ComboBoxItem> </ComboBox> <Button x:Name="CreateThreadPoolWorkItemButton" Content="Create" Click="CreateThreadPoolWorkItem" IsEnabled="True" /> <Button x:Name="CancelThreadPoolWorkItemButton" Content="Cancel" Click="CancelThreadPoolWorkItem" IsEnabled="False"/>
//显示 状态和结果 : <TextBlock x:Name="WorkItemInfo" /> <TextBlock x:Name="WorkItemStatus" Text="Not created" />
相应的 C# :
页面中的变量 :
//IAsyncAction : 表示异步操作。 public IAsyncAction ThreadPoolWorkItem;
//指定相对于线程池中其他工作项的工作项的优先级。 public WorkItemPriority WorkItemPriority = WorkItemPriority.Normal; public Status WorkItemStatus;
按钮 “Create” :
private void CreateThreadPoolWorkItem(object sender, RoutedEventArgs args) { //指定循环调用的次数 long maxCount = 10000000; // 根据指定工作项的优先级创建一个线程池。 switch (Priority.SelectionBoxItem.ToString()) { case "Low": WorkItemPriority = WorkItemPriority.Low; break; case "Normal": WorkItemPriority = WorkItemPriority.Normal; break; case "High": WorkItemPriority = WorkItemPriority.High; break; } //根据指定的优先级创建工作项。 ThreadPoolWorkItem = Windows.System.Threading.ThreadPool.RunAsync( (source) => { // 执行线程池的工作项。 long count = 0; long oldProgress = 0; while (count < maxCount) { //如果工作项还没有开始就调用了 workItem.Cancel 方法,工作项 //就会被终止。工作项如果开始工作了,那么它就会一直运行到结束,除非它 //支持“取消”操作。 //如果让工作项支持“取消”操作,这个工作项应该检查 IAsyncAction.Status //是否为取消操作,并且当取消的时候执行退出操作 if (source.Status == AsyncStatus.Canceled) { break; } // 模拟执行。 System.Threading.Interlocked.Increment(ref count); // 在 UI 上更新工作项的进度。 long currentProgress = (long)(((double)count / (double)maxCount) * 100); if (currentProgress > oldProgress) { // 只有进度值发生了改变才更新。 //创建工作项并指定其相对于线程池中其他工作项的优先级。 var ignored = Dispatcher.RunAsync( CoreDispatcherPriority.High, () => { UpdateWorkItemProgressUI(currentProgress); }); } oldProgress = currentProgress; } }, WorkItemPriority); // 注册一个完成的事件处理方法,当运行的工作项完成或取消时调用。
ThreadPoolWorkItem.Completed = new AsyncActionCompletedHandler( async (IAsyncAction source, AsyncStatus status) => { await Dispatcher.RunAsync( CoreDispatcherPriority.High, () => { switch (status) { case AsyncStatus.Started: //指定异步操作的状态。 操作已开始。 UpdateUI(Status.Started); break; case AsyncStatus.Completed: UpdateUI(Status.Completed); break; case AsyncStatus.Canceled: //操作已取消。
UpdateUI(Status.Canceled); break; } }); }); UpdateUI(Status.Started); }
更新 UI :
public void UpdateUI(Status status) { WorkItemStatus.Text = status.ToString("g"); WorkItemInfo.Text = string.Format("Work item priority = {0}", WorkItemPriority.ToString("g")); bool createButtonEnabled = (status != Status.Started); CreateThreadPoolWorkItemButton.IsEnabled = createButtonEnabled; CancelThreadPoolWorkItemButton.IsEnabled = !createButtonEnabled; } public void UpdateWorkItemProgressUI(long percentComplete) { WorkItemStatus.Text = string.Format("Progress: {0}%", percentComplete.ToString()); }
取消按钮 :
private void CancelThreadPoolWorkItem(object sender, RoutedEventArgs args) { if (ThreadPoolWorkItem != null) { ThreadPoolWorkItem.Cancel(); } }