多線程之線程池: 延遲執行, 周期執行, 在線程池中找一個線程去執行指定的方法
介紹
重新想象 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