C# 从主窗体调用方法在子窗体/线程上运行
我正在使用WinForms C#.NET 4.6 我有三张表格。Main、Form1和Form2每个窗体都在不同的线程上运行。 Form1和Form2具有Arction LightningChart控件。。每个表单都有一个名为“PlotUpdate”的方法来使用随机值更新图表C# 从主窗体调用方法在子窗体/线程上运行,c#,lightningchart,C#,Lightningchart,我正在使用WinForms C#.NET 4.6 我有三张表格。Main、Form1和Form2每个窗体都在不同的线程上运行。 Form1和Form2具有Arction LightningChart控件。。每个表单都有一个名为“PlotUpdate”的方法来使用随机值更新图表 主窗体有一个计时器,每100ms触发一次。我想从主计时器滴答事件调用PlotUpdate来更新Form1和Form2上的图表。PlotUpdate方法在Arction LightningChart控件置于主窗体中时有效,否
主窗体有一个计时器,每100ms触发一次。我想从主计时器滴答事件调用PlotUpdate来更新Form1和Form2上的图表。PlotUpdate方法在Arction LightningChart控件置于主窗体中时有效,否则无效 我怎样才能做到这一点 MainForm.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
namespace MultipleUIThreads
{
public partial class MainForm : Form
{
const int FormSeriesCount = 3;
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
public MainForm()
{
InitializeComponent();
myTimer.Interval = 100;
myTimer.Tick += myTimer_Tick;
myTimer.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
// Start new UI thread for Form3
Thread thread1 = new Thread(() =>
{
Form1 f1 = new Form1();
Application.Run(f1);
});
thread1.Start();
// Start new UI thread for Form2
Thread thread2 = new Thread(() =>
{
Form2 f2 = new Form2();
Application.Run(f2);
});
thread2.Start();
}
private void myTimer_Tick(object sender, EventArgs e)
{
//What shall I write here
}
}
}
using Arction.WinForms.Charting;
using Arction.WinForms.Charting.Axes;
using Arction.WinForms.Charting.SeriesXY;
using Arction.WinForms.Charting.Views.ViewXY;
namespace MultipleUIThreads
{
class ChartCreator
{
public static void InitChart(LightningChartUltimate ulChart)
{
ulChart.BeginUpdate();
ViewXY view = ulChart.ViewXY;
AxisX xAxis = view.XAxes[0];
xAxis.SetRange(0, 20);
xAxis.ScrollMode = XAxisScrollMode.Scrolling;
view.YAxes.Clear();
for (int seriesIndex = 0; seriesIndex < 1; seriesIndex++)
{
AxisY yAxis = new AxisY(view);
yAxis.SetRange(-100, 100);
view.YAxes.Add(yAxis);
PointLineSeries line = new PointLineSeries(view, xAxis, yAxis);
line.PointsVisible = false;
line.LineStyle.Color = DefaultColors.SeriesForBlackBackground[seriesIndex];
view.PointLineSeries.Add(line);
}
view.DropOldSeriesData = true;
view.AxisLayout.YAxesLayout = YAxesLayout.Stacked;
ulChart.EndUpdate();
}
}
}
Form1.cs/Form2.cs是相似的
using System;
using System.Windows.Forms;
using Arction.WinForms.Charting;
namespace MultipleUIThreads
{
public partial class Form1 : Form
{
int _pointsAdded = 0;
Random _rand = new Random();
public Form1()
{
InitializeComponent();
ChartCreator.InitChart(LChart);
}
public void PlotUpdate()
{
LChart.BeginUpdate();
double x = _pointsAdded * 0.1;
for (int i = 0; i < 1; i++)
{
SeriesPoint[] points = new SeriesPoint[1];
points[0].X = x;
points[0].Y = _rand.Next(-100, 100);
LChart.ViewXY.PointLineSeries[i].AddPoints(points, false);
}
LChart.ViewXY.XAxes[0].ScrollPosition = x;
LChart.EndUpdate();
_pointsAdded++;
}
}
}
使用系统;
使用System.Windows.Forms;
使用Arction.WinForms.Charting;
命名空间多线程
{
公共部分类Form1:Form
{
int _pointsAdded=0;
随机_rand=新随机();
公共表格1()
{
初始化组件();
ChartCreator.InitChart(LChart);
}
公共更新()
{
LChart.BeginUpdate();
双x=_点加上*0.1;
对于(int i=0;i<1;i++)
{
SeriesPoint[]点=新SeriesPoint[1];
点[0].X=X;
点[0]。Y=_rand.Next(-100100);
LChart.ViewXY.PointLineSeries[i].AddPoints(points,false);
}
LChart.ViewXY.XAxes[0].ScrollPosition=x;
LChart.EndUpdate();
_pointsAdded++;
}
}
}
ChartCreator.cs
using System;
using System.Collections.Generic;
using System.Threading;
using System.Windows.Forms;
namespace MultipleUIThreads
{
public partial class MainForm : Form
{
const int FormSeriesCount = 3;
static System.Windows.Forms.Timer myTimer = new System.Windows.Forms.Timer();
public MainForm()
{
InitializeComponent();
myTimer.Interval = 100;
myTimer.Tick += myTimer_Tick;
myTimer.Start();
}
private void Form1_Load(object sender, EventArgs e)
{
// Start new UI thread for Form3
Thread thread1 = new Thread(() =>
{
Form1 f1 = new Form1();
Application.Run(f1);
});
thread1.Start();
// Start new UI thread for Form2
Thread thread2 = new Thread(() =>
{
Form2 f2 = new Form2();
Application.Run(f2);
});
thread2.Start();
}
private void myTimer_Tick(object sender, EventArgs e)
{
//What shall I write here
}
}
}
using Arction.WinForms.Charting;
using Arction.WinForms.Charting.Axes;
using Arction.WinForms.Charting.SeriesXY;
using Arction.WinForms.Charting.Views.ViewXY;
namespace MultipleUIThreads
{
class ChartCreator
{
public static void InitChart(LightningChartUltimate ulChart)
{
ulChart.BeginUpdate();
ViewXY view = ulChart.ViewXY;
AxisX xAxis = view.XAxes[0];
xAxis.SetRange(0, 20);
xAxis.ScrollMode = XAxisScrollMode.Scrolling;
view.YAxes.Clear();
for (int seriesIndex = 0; seriesIndex < 1; seriesIndex++)
{
AxisY yAxis = new AxisY(view);
yAxis.SetRange(-100, 100);
view.YAxes.Add(yAxis);
PointLineSeries line = new PointLineSeries(view, xAxis, yAxis);
line.PointsVisible = false;
line.LineStyle.Color = DefaultColors.SeriesForBlackBackground[seriesIndex];
view.PointLineSeries.Add(line);
}
view.DropOldSeriesData = true;
view.AxisLayout.YAxesLayout = YAxesLayout.Stacked;
ulChart.EndUpdate();
}
}
}
使用Arction.WinForms.Charting;
使用Arction.WinForms.Charting.Axes;
使用Arction.WinForms.Charting.SeriesXY;
使用Arction.WinForms.Charting.Views.ViewXY;
命名空间多线程
{
类图表创建者
{
公共静态无效初始图(LightningChart)
{
ulChart.BeginUpdate();
ViewXY view=ulChart.ViewXY;
axix-xAxis=view.XAxes[0];
xAxis.SetRange(0,20);
xAxis.ScrollMode=xaxiscollmode.Scrolling;
view.YAxes.Clear();
对于(int seriesIndex=0;seriesIndex<1;seriesIndex++)
{
AxisY yAxis=新AxisY(视图);
yAxis.SetRange(-100100);
view.YAxes.Add(yAxis);
PointLineSeries直线=新的PointLineSeries(视图、X轴、Y轴);
line.PointsVisible=false;
line.LineStyle.Color=DefaultColors.SeriesForBlackBackground[seriesIndex];
view.PointLineSeries.Add(行);
}
view.DropOldSeriesData=true;
view.AxisLayout.YAxesLayout=YAxesLayout.Stacked;
ulChart.EndUpdate();
}
}
}
你走在正确的轨道上。代码
// Start new UI thread for Form3
Thread thread1 = new Thread(() =>
{
Form1 f1 = new Form1();
Application.Run(f1);
});
thread1.Start();
将为您创建一个运行在自己线程上的Windows窗体。只是别忘了UI线程应该作为ApparationState.STA运行。因此,包括linethread1.SetApartmentState(ApartmentState.STA)代码>
这不是创造财富的唯一途径
现在介绍LightningChart控件/组件。对于大多数UI控件,应该在主线程中更新LightningChart(R).NET。在应用程序中使用另一个(后台)线程时,来自该线程的所有UI更新都必须通过调用(WinForms中的Control.Invoke()。
已经有了WPF解决方案。WinForms应用程序应该/可以遵循非常相似的逻辑。
您首先需要的是计划稍后操作/访问的图表列表。第二,不要忘记那个图表。应该设置父级,即表单本身或该表单中的面板。最后,为要在Tick handler中更新的每个LightningChart实例调用call Chart.Invoke()。比如说,
private void myTimer_Tick(object sender, EventArgs e)
{
if(_chartContainers.Count == 0)
{
for (int i = 0; i < _chartForms.Count; i++)
{
//ChartWindow cw = new ChartWindow(_chartForms[i]);
_chartForms[i].Invoke((System.Action)delegate
{
ChartWindow cw = new ChartWindow(_chartForms[i]);
_chartContainers.Add(cw);
});
}
}
if (_chartForms.Count == 0)
return;
for (int iChart = 0; iChart < _chartForms.Count; iChart++)
{
ChartWindow cw = _chartContainers[iChart];
cw.Chart.Invoke((System.Action)delegate
{
cw.AddSeriesPoints(new double[] { random.NextDouble()*10 });
});
}
}
private void myTimer\u勾选(对象发送方,事件参数e)
{
如果(_chartContainers.Count==0)
{
对于(int i=0;i<\u chartForms.Count;i++)
{
//ChartWindow cw=新的ChartWindow(_chartForms[i]);
_chartForms[i].Invoke((System.Action)委托
{
ChartWindow cw=新的ChartWindow(_chartForms[i]);
_添加(cw);
});
}
}
如果(_chartForms.Count==0)
返回;
对于(int-iChart=0;iChart<\u chartForms.Count;iChart++)
{
ChartWindow cw=_chartContainers[iChart];
cw.Chart.Invoke((System.Action)委托
{
cw.AddSeriesPoints(新的double[]{random.NextDouble()*10});
});
}
}
第一部分实际上是使用(空)窗体的线程在其中创建图表窗口(基本上创建图表并将父窗体设置为特定窗体)
第二部分为每个图表添加新的随机点。在这里,AddSeriesPoints在ChartWindow类中定义了自定义方法,用于添加点数组和滚动。您也可以直接使用LightningChart方法。看起来,打开表单的方式让您受益匪浅,无需在不同的线程中运行表单并调用应用程序。运行。只需创建表单,然后调用ShowDialog
@常规,好吧,我想在不同的线程上运行表单,因为以后在同一UI线程上运行渲染会非常激烈。仅在不创建新线程的情况下使用ShowDialog()将在同一线程上运行所有窗体。这是我想避免的,这更有意义。第一个问题是表单的范围form1f1=newform1()代码>您需要全局存储它们(作为实例成员)。还有什么?“主窗体有一个每100ms触发一次的计时器。我想从主计时器滴答事件调用PlotUpdate来更新Form1和Form2上的图表。”为什么不在Fo上弹出一个计时器呢