C#(blazor实现)中线程的开始、暂停、继续、停止与定时关闭代码实现

举报
Further_Step 发表于 2024/12/28 22:26:35 2024/12/28
【摘要】 C# 中线程控制:使用 CancellationTokenSource 和 ManualResetEvent在现代应用程序中,线程控制是一个重要的主题,尤其是在处理并发任务时。C# 提供了多种工具来管理线程的启动、停止和同步。在本文中,我们将深入探讨如何使用 CancellationTokenSource 类来控制线程的开始与停止,以及如何使用 ManualResetEvent 类来实现线...

image.png

C# 中线程控制:使用 CancellationTokenSourceManualResetEvent

在现代应用程序中,线程控制是一个重要的主题,尤其是在处理并发任务时。C# 提供了多种工具来管理线程的启动、停止和同步。在本文中,我们将深入探讨如何使用 CancellationTokenSource 类来控制线程的开始与停止,以及如何使用 ManualResetEvent 类来实现线程的阻塞与非阻塞。

代码实现

我们将通过一个 Blazor 组件示例来展示这些概念。以下是 TaskTest.razor 的完整代码实现:

TaskTest.razor

@page "/Task"
<div class="main">
    <h1>线程控制</h1>
    <p role="status" style="margin:20px 0;">提示信息: @_message</p>
    <button @onclick="Start" style="margin-right:20px;">开始</button>
    <button @onclick="Pause" style="margin-right:20px;">暂停</button>
    <button @onclick="Continue" style="margin-right:20px;">继续</button>
    <button @onclick="Stop" style="margin-right:20px;">停止</button>
    <input type="number" @bind-value="@_milliseconds" />
    <button @onclick="Timing" style="margin-right:20px;">定时取消</button>
</div>

@code {
    private string _message = "";
    private CancellationTokenSource? _tokenSource; // 用于终止线程
    private ManualResetEvent? _manualReset; // 用于阻塞/恢复线程运行
    private int _milliseconds = 1000;

    private void Start() {
        if (_tokenSource != null) {
            Pause();
            Thread.Sleep(200);
            _message = "一次只能创建一个线程!请点击继续开启当前线程!";
            StateHasChanged();
            return;
        }
        _tokenSource = new();
        _manualReset = new(true);
        int i = 0;
        Task.Run(() => {
            while (!_tokenSource.Token.IsCancellationRequested) {
                _manualReset.WaitOne(); // 根据是否收到信号判断是否阻塞当前线程
                Thread.Sleep(200);
                _message = $"线程{Environment.CurrentManagedThreadId}正在运行第{++i}次{Environment.NewLine}";
                InvokeAsync(() => { StateHasChanged(); return Task.CompletedTask; });
            }
            CancelSuccess();
            InvokeAsync(() => { StateHasChanged(); return Task.CompletedTask; });
        }, _tokenSource.Token);
    }

    private void Pause() {
        _manualReset?.Reset(); // 阻塞所有调用WaitOne()的线程
    }

    private void Continue() {
        _manualReset?.Set(); // WaitOne()阻塞的等待线程将恢复并继续执行
    }

    private void Stop() {
        _tokenSource?.Cancel(); // 关闭线程
        StateHasChanged();
    }

    private void Timing() {
        _tokenSource?.CancelAfter(_milliseconds); // 定时关闭线程
    }

    private void CancelSuccess() {
        _tokenSource = null;
        _manualReset = null;
        _message = "线程取消成功!";
    }
}

TaskTest.razor.css

.main {
    padding: 20px;
    background: gray;
}
button {
    display: inline-block;
    margin: 0;
    padding: 0 20px;
    height: 40px;
    border: 1px solid #fff;
    border-radius: 4px;
    font-size: 14px;
    color: #fff;
    background: rgba(68, 68, 68, 0.5);
    cursor: pointer;
}
input {
    height: 40px;
    border: none;
    border-radius: 4px;
    font-size: 12px;
    color: #fff;
    text-indent: 1em;
    background: #444;
    outline: none;
}

界面展示

在上述代码中,我们创建了一个简单的用户界面,允许用户控制线程的启动、暂停、继续和停止。以下是界面的示例截图:

线程控制界面

代码解析

1. 使用 CancellationTokenSource 控制线程

CancellationTokenSource 是一个用于管理线程取消的类。通过创建一个 CancellationTokenSource 实例,我们可以在需要时请求取消线程的执行。在 Start 方法中,我们检查是否已有线程在运行,如果没有,则创建一个新的 CancellationTokenSourceManualResetEvent 实例。

if (_tokenSource != null) {
    Pause();
    Thread.Sleep(200);
    _message = "一次只能创建一个线程!请点击继续开启当前线程!";
    StateHasChanged();
    return;
}
_tokenSource = new();

2. 使用 ManualResetEvent 实现线程阻塞与恢复

ManualResetEvent 是一个线程同步类,允许我们控制线程的执行。通过调用 Reset 方法,我们可以阻塞线程,而调用 Set 方法则可以恢复线程的执行。

private void Pause() {
    _manualReset?.Reset(); // 阻塞所有调用WaitOne()的线程
}

private void Continue() {
    _manualReset?.Set(); // 恢复线程执行
}

3. 定时取消线程

Timing 方法中,我们使用 CancelAfter 方法来设置一个定时器,指定在一定时间后自动取消线程。这使得我们可以灵活地控制线程的生命周期。

private void Timing() {
    _tokenSource?.CancelAfter(_milliseconds); // 定时关闭线程
}

应用场景

这种线程控制机制在许多应用场景中都非常有用,例如:

  1. 后台任务处理:在需要处理长时间运行的任务时,可以使用这些机制来控制任务的执行。
  2. 用户交互:在用户界面中,允许用户通过按钮来控制任务的执行状态,提升用户体验。
  3. 资源管理:在资源有限的情况下,能够及时停止不必要的线程,节省系统资源。

总结

本文介绍了如何在 C# 中使用 CancellationTokenSourceManualResetEvent 来控制线程的启动、停止和阻塞。通过示例代码,我们展示了如何在 Blazor 应用中实现这些功能。掌握这些技术将有助于开发更高效和响应迅速的应用程序。希望这篇文章能为你在 C# 线程管理方面提供一些有用的见解和实践经验。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。