C# 使用ManualResetEvent和CancellationTokenSource实现后台数据获取和界面中的chart刷新功能的启动、暂停和停止功能 给出完整程序
时间: 2024-09-11 19:11:56 浏览: 56
C#-【多线程篇】AutoResetEvent和ManualResetEvent的区别(中级)
在C#中,`ManualResetEvent` 和 `CancellationTokenSource` 是用于控制异步操作并发性和取消请求的两个工具。`ManualResetEvent` 主要用来同步等待某个事件的发生,而 `CancellationTokenSource` 可以让用户通过 `CancellationToken` 来中断长时间运行的任务。
下面是一个简单的示例,展示了如何使用这两个类来实现后台数据获取(例如从API或其他源),并在界面上的图表上实时更新。这个例子假设我们有一个`DataFetcher`类负责获取数据,并且`ChartUpdater`类负责显示更新的数据:
```csharp
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms.DataVisualization.Charting;
// 定义数据获取类
public class DataFetcher
{
private ManualResetEvent _event = new ManualResetEvent(false);
public event EventHandler<DataReceivedEventArgs> DataReceived;
public async Task GetData(CancellationToken token)
{
while (!token.IsCancellationRequested)
{
try
{
// 模拟数据获取
var newData = await FetchNewDataAsync();
// 更新数据并触发事件
UpdateData(newData);
// 等待一段时间再获取下一批数据
await Task.Delay(5000, token.Token); // 5秒延迟
// 如果有取消请求,直接结束循环
if (token.IsCancellationRequested) break;
_event.Set(); // 设置事件,唤醒等待者
}
catch (OperationCanceledException)
{
// 用户请求取消,忽略异常
}
}
_event.Reset(); // 任务完成时清空事件
}
private void UpdateData(Data data)
{
// 实现更新图表的逻辑...
OnDataReceived(new DataReceivedEventArgs(data));
}
private void OnDataReceived(DataReceivedEventArgs e)
{
if (DataReceived != null) DataReceived(this, e);
}
}
// 定义事件处理类
public class ChartUpdater : IDisposable
{
private readonly CancellationTokenSource _cts = new CancellationTokenSource();
private Chart _chart;
public ChartUpdater(Chart chart)
{
_chart = chart;
_chart.DataSeries[0].IsDataSourceUpdated += DataSeriesUpdated;
}
public void Start()
{
_cts.Start();
}
public void Pause()
{
_cts.Cancel();
}
public void Stop()
{
_cts.Dispose();
_chart.DataSeries[0].IsDataSourceUpdated -= DataSeriesUpdated;
}
private void DataSeriesUpdated(object sender, DataSourceUpdateEventArgs e)
{
// 图表数据更新后调用此方法
// 在这里绘制或更新图表
}
public void Dispose()
{
_cts?.Cancel();
_cts?.Dispose();
}
}
// 在窗口初始化或按钮点击事件中
private void Form1_Load(object sender, EventArgs e)
{
DataFetcher fetcher = new DataFetcher();
ChartUpdater updater = new ChartUpdater(chartControl);
// 启动数据获取
updater.Start();
fetcher.GetData(updater._cts.Token).ContinueWith(t =>
{
if (t.IsFaulted && t.Exception is OperationCanceledException)
{
MessageBox.Show("数据获取已取消");
}
});
}
```
在这个例子中,当用户开始、暂停或停止时,`ChartUpdater`会相应地影响`GetData`任务,使其暂停或取消。注意,这只是一个基本的框架,实际应用中需要替换为适合你的数据获取和图表更新逻辑。
阅读全文