C# 使用ManualResetEvent和CancellationTokenSource实现后台数据读取和界面中的chart刷新功能的启动、暂停和停止 给出完整程序
时间: 2024-09-11 17:11:56 浏览: 45
C#-【多线程篇】AutoResetEvent和ManualResetEvent的区别(中级)
在C#中,`ManualResetEvent`和`CancellationTokenSource`通常用于控制异步操作的开始、暂停和停止,特别是在处理后台数据读取的同时保持用户界面的响应。以下是一个简单的示例,展示了如何结合这两个类实现这个功能:
```csharp
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms.DataVisualization.Charting;
public class BackgroundDataProcessor
{
private ManualResetEvent _startEvent = new ManualResetEvent(false);
private CancellationTokenSource _cancellationTokenSource;
private Chart _chart;
public void StartBackgroundTask(Chart chart)
{
_chart = chart;
_cancellationTokenSource = new CancellationTokenSource();
_startEvent.Set();
Task.Run(() => ReadAndRefreshData(_cancellationTokenSource.Token), _cancellationTokenSource.Token);
}
public void Pause()
{
if (!_cancellationTokenSource.IsCancellationRequested)
_cancellationTokenSource.Cancel();
}
public void Stop()
{
_cancellationTokenSource?.Cancel();
_startEvent.Reset();
}
private async void ReadAndRefreshData(CancellationToken cancellationToken)
{
try
{
while (!_cancellationTokenSource.IsCancellationRequested && _startEvent.WaitOne(500))
{
// 模拟后台数据读取
List<DataPoint> dataPoints = await GetDataAsync(cancellationToken);
// 更新图表
_chart.Series["Series1"].Points.Clear();
foreach (DataPoint dp in dataPoints)
_chart.Series["Series1"].Points.Add(dp);
// 图表更新间隔或其他UI操作...
}
}
catch (OperationCanceledException)
{
Console.WriteLine("Operation was canceled.");
}
finally
{
_cancellationTokenSource.Dispose();
}
}
private async Task<List<DataPoint>> GetDataAsync(CancellationToken cancellationToken)
{
// 实现实际的数据获取逻辑,例如网络请求
var random = new Random();
var dataPoints = Enumerable.Range(1, 10).Select(i => new DataPoint(i, random.Next(0, 100))).ToList();
return dataPoints;
}
}
// 使用示例
public partial class MainForm : Form
{
BackgroundDataProcessor processor;
public MainForm()
{
InitializeComponent();
processor = new BackgroundDataProcessor();
btnStart.Click += BtnStart_Click;
btnPause.Click += BtnPause_Click;
btnStop.Click += BtnStop_Click;
}
private async void BtnStart_Click(object sender, EventArgs e)
{
processor.StartBackgroundTask(chart1);
}
private void BtnPause_Click(object sender, EventArgs e)
{
processor.Pause();
}
private void BtnStop_Click(object sender, EventArgs e)
{
processor.Stop();
}
}
```
在这个例子中,`StartBackgroundTask`方法启动了后台任务,并设置了一个手动重置事件`_startEvent`来控制数据读取是否继续。当点击"开始"按钮时,会触发`ReadAndRefreshData`异步任务,它会在等待信号(直到收到`_startEvent`的Set)时不断读取和刷新数据。
用户可以点击"暂停"按钮取消`CancellationTokenSource`,中断当前的数据读取。如果需要完全退出,点击"停止"按钮将取消令牌并重置`_startEvent`。
阅读全文