C#中多线程更新Chart控件与BeginInvoke
最近把之前修改的MFC平台上的监控程序移植到C#上,需要用到图形控件显示监控曲线,C#中的现成的Chart控件为首选,但是在后台线程中更新Chart数据是总是在接收数据并刷新Chart时Chart控件上的图形变成一个大红叉,如下图所示,一个下午都没查出来为什么,后来在论坛上看到有人说需要利用BeginInvoke委托,就去看了MSDN上的介绍,按照使用说明改写后真的能刷新了,写下代码,以备不时之需。
代码
public delegate void ChartDelegate(Chart _Chart, DataTable _dataTable);//声明委托方法
private object[] invokeChartData = new object[2];
//声明委托参数,[0]位存放委托方法的第一个参数,[1]位存放委托方法的第二个参数
invokeChartData[0] = CurChart;//定义[0]位参数位需要更新的Chart控件
invokeChartData[1] = dataTable;//定义[1]位为Chart中的数据
/// <summary>
/// 执行委托,可以在其他线程中修改dataTable,再调用该方法来执行委托
/// </summary>
public void UpdateChart()
{
CurChart.BeginInvoke(new ChartDelegate(ChartDelegateMethod), invokeChartData);
}
/// <summary>
/// 委托方法
/// </summary>
/// <param name="_Chart">要更新的Chart控件</param>
/// <param name="_dataTable">要写入的数据</param>
public void ChartDelegateMethod(Chart _Chart, DataTable _dataTable)
{
_Chart.Series[0].Points.DataBind(this.dataTable.AsEnumerable(), "日期", "数据", "");
}
MSDN中用下面的代码示例演示 BeginInvoke 方法的用法。
public delegate void MyDelegate(Label myControl, string myArg2);
private void Button_Click(object sender, EventArgs e)
{
object[] myArray = new object[2];
myArray[0] = new Label();
myArray[1] = "Enter a Value";
myTextBox.BeginInvoke(new MyDelegate(DelegateMethod), myArray);
}
public void DelegateMethod(Label myControl, string myCaption)
{
myControl.Location = new Point(16,16);
myControl.Size = new Size(80, 25);
myControl.Text = myCaption;
this.Controls.Add(myControl);
}
修改后能正常打印控件,如下图: