C# 使用ManualResetEvent和CancellationTokenSource实现后台数据获取(方法为GetValueData)和界面中的chart刷新(方法为GetChartData)功能的启动、暂停和停止功能 给出完整程序
时间: 2024-09-11 08:12:39 浏览: 46
在C#中,你可以使用`System.Threading.Tasks.Task`和`System.Threading.CancellationTokenSource`以及`System.Threading.ManualResetEvent`来实现后台任务的管理和UI线程的交互。这里是一个简单的示例,展示如何创建一个后台数据获取任务,以及通过`CancellationToken`和`ManualResetEvent`控制其开始、暂停和停止:
```csharp
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms.DataVisualization.Charting;
public partial class MainForm : Form
{
private CancellationTokenSource _cancellationTokenSource;
private ManualResetEventSlim _eventWaitHandle;
public MainForm()
{
InitializeComponent();
_eventWaitHandle = new ManualResetEventSlim(initialState: false);
GetValueDataAsync();
}
private async void GetValueDataAsync()
{
try
{
_cancellationTokenSource = new CancellationTokenSource();
while (!_cancellationTokenSource.IsCancellationRequested)
{
// 模拟后台数据获取,实际操作中替换为数据库或其他API请求
var data = await GetChartData(_cancellationTokenSource.Token);
if (data != null)
{
lock (_eventWaitHandle) // 为了线程安全更新图表
{
UpdateChart(data);
}
_eventWaitHandle.WaitOne(); // 等待UI线程处理完再继续获取数据
}
else
{
break; // 如果数据为空,结束循环
}
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Task was cancelled.");
}
finally
{
_cancellationTokenSource?.Cancel(); // 取消token并清理资源
_eventWaitHandle.Set(); // 设置事件以通知主线程任务已结束
}
}
private async Task<Dictionary<int, double>> GetChartData(CancellationToken cancellationToken)
{
// 这里可以改为异步获取数据
return await Task.Delay(1000, cancellationToken); // 示例,延迟获取模拟数据
}
private void UpdateChart(Dictionary<int, double> data)
{
chart1.Series.Clear(); // 清空旧系列
foreach (var point in data)
{
chart1.Series.Add(new Series($"Series_{point.Key}"));
chart1.Series[point.Key].Points.AddXY(point.Key, point.Value);
}
}
private void buttonStart_Click(object sender, EventArgs e)
{
_eventWaitHandle.Reset(); // 重置事件以便开始获取数据
}
private void buttonPause_Click(object sender, EventArgs e)
{
_cancellationTokenSource.Cancel(); // 如果正在运行,则暂停
_eventWaitHandle.WaitOne(); // 确保UI处理完当前数据
}
private void buttonStop_Click(object sender, EventArgs e)
{
_cancellationTokenSource.Cancel(); // 请求取消任务
_eventWaitHandle.Set(); // 让主线程知道任务已终止
}
private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
{
// 关闭窗口时,确保任务已停止
_cancellationTokenSource?.Cancel();
}
阅读全文