重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

简介: 原文:重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法[源码下载] 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执...
原文: 重新想象 Windows 8 Store Apps (42) - 多线程之线程池: 延迟执行, 周期执行, 在线程池中找一个线程去执行指定的方法

[源码下载]


重新想象 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
[源码下载]

目录
相关文章
|
7月前
|
Ubuntu Unix Linux
在Windows上轻松安装和使用Ubuntu的方法详解
继续点击“Continue”按钮以继续安装流程,随后选择清理磁盘并安装操作系统的选项。 接下来,在安装过程中,你需要选择时区。为了与你的地理位置相匹配,请选择中国上海作为你的时区设置。 在安装过程中,你还需要设置计算机的名称以及账号密码。请务必牢记这些信息,因为它们将作为你登录系统的凭证。
|
8月前
|
Linux Windows
Windows 10/11从官网下载ISO的方法
本文介绍了两种从微软官网下载Windows 10/11 ISO镜像的方法。一是通过修改浏览器User Agent为Linux系统,使官网提供ISO下载链接;二是使用UUPDUMP工具,从官网下载并转换为ISO格式,支持最新开发版,操作简便。
|
6月前
|
存储 Oracle Java
|
6月前
|
运维 iOS开发 Windows
windows电脑备案ios APP获取公钥和证书指纹Sha-1值的方法
在阿里云进行APP备案、在备案IOS端的环节的时候,发现需要我们将p12证书安装在电脑上,再用xcode或或钥匙串访问来获取这个证书的公钥和sha-1值。 但是大部分开发uniapp应用的同学们,或者进行发布的运维人员的电脑都是windows,无法按照阿里云的教程来获取ios的公钥和sha-1。备案就被卡主了。 这里介绍下另一个方法,就是使用香蕉云编来在线上传证书获取。如下图所示,打开香蕉云编后,找到下图这个功能
951 0
|
8月前
|
Java
创建线程的方法
Java中实现多线程有四种方式:1. 继承Thread类,简单但占用继承机会,耦合度高;2. 实现Runnable接口,推荐方式,任务与线程解耦,支持Lambda;3. 实现Callable接口配合FutureTask,可获取返回值和异常;4. 使用线程池(ExecutorService),企业推荐,管理线程生命周期,提升性能,支持多种线程池类型。
183 1
|
9月前
|
Java 数据挖掘 调度
Java 多线程创建零基础入门新手指南:从零开始全面学习多线程创建方法
本文从零基础角度出发,深入浅出地讲解Java多线程的创建方式。内容涵盖继承`Thread`类、实现`Runnable`接口、使用`Callable`和`Future`接口以及线程池的创建与管理等核心知识点。通过代码示例与应用场景分析,帮助读者理解每种方式的特点及适用场景,理论结合实践,轻松掌握Java多线程编程 essentials。
622 5
|
存储 安全 虚拟化
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
1289 0
Windows 11 绕过 TPM 方法总结,通用免 TPM 镜像下载 (2025 年 2 月更新)
|
缓存 安全 Java
【JavaEE】——单例模式引起的多线程安全问题:“饿汉/懒汉”模式,及解决思路和方法(面试高频)
单例模式下,“饿汉模式”,“懒汉模式”,单例模式下引起的线程安全问题,解锁思路和解决方法
|
Java 程序员 调度
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
创建线程的五种方式,Thread常见方法(守护进程.setDaemon() ,isAlive),start和run方法的区别,如何提前终止一个线程,标志位,isinterrupted,变量捕获
|
存储 缓存 安全
硬盘数据恢复:恢复硬盘数据的9个实用方法(Windows版)
无论是工作文档、家庭照片,还是其他珍贵的数字资产,数据丢失总是一件让人头疼的事情。然而,当硬盘发生问题时,不必过于慌张——只要正确应对,许多数据都可以被成功恢复。本文将从常见数据丢失原因到具体恢复方法,为您提供全面的硬盘数据恢复指导。