C#(blazor实现)中线程的开始、暂停、继续、停止与定时关闭代码实现
Posted on 2023-03-23 13:52 Further_Step 阅读(19) 评论(0) 编辑 收藏 举报 来源C#中线程的开始与停止使用CancellationTokenSource类,阻塞与非阻塞使用ManualResetEvent类
以下为代码实现:
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;background:">开始</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>
<!--
CancellationTokenSource可以使用CreateLinkedTokenSource对多任务进行管理,实例如下:
static CancellationTokenSource c1 = new CancellationTokenSource();
static CancellationTokenSource c2 = new CancellationTokenSource();
static CancellationTokenSource c3 = new CancellationTokenSource();
static CancellationTokenSource compositeCancel = CancellationTokenSource.CreateLinkedTokenSource(c1.Token, c2.Token, c3.Token);
创建线程时将compositeCancel传递过去,当c1\c2\c3其中任意一个任务cancel,则所有任务关闭
-->
@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);// 定时关闭线程
//也可以在new对象的时候直接给他一个定时参数eg:new CancellationTokenSource(1000);
}
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;
}
界面如下图所示:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现