wpf 异步多线程实现scottplot实时绘图
在WPF中,可以使用异步多线程来实现ScottPlot的实时绘图。下面是一个简单的示例:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wpf="clr-namespace:ScottPlot.WPF;assembly=ScottPlot.WPF"
Title="MainWindow" Height="450" Width="800">
<Grid>
<wpf:ScottPlotWPF x:Name="plot" />
<Button Content="Start" Click="Button_Click" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,10,0" />
</Grid>
</Window>
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using ScottPlot;
namespace WpfApp1
{
public partial class MainWindow : Window
{
private Random random = new Random();
private Task plotTask;
private CancellationTokenSource cancellationTokenSource;
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
if (plotTask != null && plotTask.Status == TaskStatus.Running)
{
// 如果任务正在运行,则取消任务
cancellationTokenSource.Cancel();
return;
}
// 创建新的取消令牌和任务
cancellationTokenSource = new CancellationTokenSource();
CancellationToken cancellationToken = cancellationTokenSource.Token;
plotTask = Task.Run(() =>
{
// 在后台线程中生成数据并更新图形
double[] data = new double[1000];
double[] x = DataGen.Consecutive(data.Length);
while (!cancellationToken.IsCancellationRequested)
{
for (int i = 0; i < data.Length; i++)
{
data[i] = random.NextDouble();
}
// 更新图形
plot.Dispatcher.Invoke(() =>
{
plot.Clear();
plot.PlotSignal(data, sampleRate: 1.0);
plot.Render();
});
// 等待一段时间
Thread.Sleep(100);
}
}, cancellationToken);
}
}
}
在上述代码中,我们创建了一个后台线程来生成随机数据,并使用plot.Dispatcher.Invoke()
方法在UI线程上更新图形。此外,我们还使用了CancellationToken
来处理任务的取消。
当点击按钮时,如果任务正在运行,则取消之前的任务;否则,创建新的取消令牌和任务。在后台线程中,我们使用了一个无限循环来生成数据并更新图形,直到取消令牌被请求。在每次循环中,我们调用plot.Dispatcher.Invoke()
方法来更新图形,并使用Thread.Sleep()
方法来暂停一段时间,以模拟实时数据。
这样,我们就可以通过点击按钮来开始和停止实时绘图了。