我正在尝试在Windows窗体应用程序中以时间间隔来绘制数据图。
我需要在单独的线程上运行图形元素,但是我调用了三个不同的函数,不能简单地使用thread.start();
我尝试仅在其自己的线程中运行控件,但它告诉我另一个线程拥有控件。
按原样运行程序时,图表会严重滞后,这意味着它必须位于独立线程中
所有这些都需要在单独的线程上运行,因为更新时我的表单滞后了
public void GraphData()
{
var mapper = Mappers.Xy<MeasureModel>()
.X(model => model.DateTime.Ticks) //use DateTime.Ticks as X
.Y(model => model.Value); //use the value property as Y
Charting.For<MeasureModel>(mapper);
//the ChartValues property will store our values array
ChartValues = new ChartValues<MeasureModel>();
cartesianChart1.Series = new SeriesCollection
{
new LineSeries
{
Values = ChartValues,
PointGeometrySize = 1,
StrokeThickness = 2
}
};
cartesianChart1.AxisX.Add(new Axis
{
DisableAnimations = true,
LabelFormatter = value => new System.DateTime((long)value).ToString("hh:mm:ss"),
Separator = new Separator
{
Step = TimeSpan.FromSeconds(1).Ticks
}
});
var thread = new Thread(() =>
{
SetAxisLimits(System.DateTime.Now);
Timer = new System.Windows.Forms.Timer
{
Interval = 20
};
Timer.Tick += TimerOnTick;
Timer.Tick += timerdata_event;
Timer.Start();
});
thread.Start();
}
public ChartValues<MeasureModel> ChartValues { get; set; }
public System.Windows.Forms.Timer Timer { get; set; }
private void SetAxisLimits(System.DateTime now)
{
cartesianChart1.AxisX[0].MaxValue = now.Ticks + TimeSpan.FromMilliseconds(1000).Ticks; // force the axis to be 100ms ahead
cartesianChart1.AxisX[0].MinValue = now.Ticks - TimeSpan.FromSeconds(4).Ticks; // only care about the last 8 seconds
}
private void TimerOnTick(object sender, EventArgs eventArgs)
{
var now = DateTime.Now;
var queue = new Queue(tempStore);
var b = queue.Dequeue();
ChartValues.Add(new MeasureModel
{
DateTime = now,
Value = double.Parse(b.ToString())
});
SetAxisLimits(now);
if (ChartValues.Count > 100) ChartValues.RemoveAt(0);
}
答案 0 :(得分:0)
看看BackgroundWorker。它是一个系统组件,它允许线程过程异步执行其工作,并提供两个在UI线程上运行的回调事件(ProgressChanged,RunWorkerCompleted)。
答案 1 :(得分:0)
有两件事... 1. Windows窗体使用队列而不是线程,它建立在STA(单线程建筑师)事件上,尽管当我们看它时,它看起来像MTA ... 因此,第一件事,如果您在单独的线程中运行,则应与Windows队列同步...如果在使用控件时不这样做,有时甚至会导致错误
致电:this (which this mean this form instance)
this.Invoke(new Action(delegate(){ /* your Synchronized code comes here */}))
or (Action)delegate() {} as i saw in internet
第二次将计算放在背景上,执行双重缓冲之类的操作……意味着您在执行计算或绘图时既不应用也不与表单同步...
完成后,您只需应用确实在背面绘制的内容即可。...
因此您的最终代码将如下所示:
{ //New thread function
// Calculates
// Draw arts
// Synchronize
this.Invoke((Action)delegate() {
//Perform Synchronizing Code
// Apply your drawn image and graphics to your image viewer, aka picture box
}
// End of thread, or if you need something extra to be performed afterward...
}
但是,如果您无权访问该组件抽屉,请尝试查看性能。如果在后台传递参数,然后将其添加到表单中?如果初始化组件的过程比运行时更改图形的过程要少,如果看起来不错,请按照这种方式进行操作,导致在您插入某个组件时,每次更改都会导致表单重新绘制,并且会带来性能损失。>