none
VS,多线程 刷新 msChart图表 RRS feed

  • 问题

  • 使用vs编写的程序,在线程中实时读取设备的数据,存放在DataTable中,(DataTable里面的数据作为mschart的数据源),mschart里面的图形不能实现刷新?求解决办法
    2021年1月5日 14:35

答案

  • Hi O_lizhen,

    感谢您的反馈。

    根据我的测试,我建议你可以加一个timer控件,因为你把设置数据的过程全部写在了form_load事件中,这个事件只会触发一次,因此chart中的数据是不能更新的。

    你可以参考下面的代码:

    Public Class Form1
    
        Private xh_RT As Integer = -1                                           '数据行号
        Private dt As New DataTable
        Private SP1_Num As Single
        Private Thread_MyWorks, Thread_Num As System.Threading.Thread           '时间线程(横坐标),数据线程(纵坐标)
        Private Position_Monitor_Complete, Mywork_Complete As Boolean           '结束标志
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            '设置数据线程
            dt.Columns.Add("tnow", Type.GetType("System.DateTime"))
            dt.Columns.Add("SP1", Type.GetType("System.Single"))
            For i = 0 To 1000                                                   '新建存储数据数据库
                dt.Rows.Add()
            Next
            Timer1.Interval = 1000
            Timer1.Start()
    
        End Sub
        Private Sub Num_Monitor()
            Position_Monitor_Complete = False
            Threading.Interlocked.Exchange(Position_Monitoring, 1)
    
            Do Until Position_Monitor_Complete
                SP1_Num += 1
                Sleep(2000)
            Loop
    
    
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Position_Monitoring, 0)
                Thread_Num.Abort()
            Catch
                Thread_Num = Nothing
            End Try
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Position_Monitor_Complete = True
            Sleep(100)
            Mywork_Complete = True
    
            TextBox1.Text = "停止数据采集"
            Timer1.Stop()
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 0
    
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 1
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 5
    
            Chart1.Series.Clear()                                               '清空
    
            Chart1.Series.Add(0)                                                '//添加
            Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Spline
            Chart1.Series(0).IsXValueIndexed = True
            Chart1.Series(0).XValueMember = "tnow"
            Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "dd-HH:mm"
            Chart1.Series(0).YValueMembers = "SP1"
            Chart1.Series(0).LegendText = "SP1"
            Chart1.Series(0).BorderColor = Color.FromArgb(185, 26, 59, 125)
    
            Chart1.DataSource = dt
            Chart1.DataBind()
    
            Thread_Num = New Thread(AddressOf Num_Monitor)                      '新建线程 数据(纵坐标)
            Thread_Num.IsBackground = True                                      '设置为后台线程
            Thread_Num.Priority = ThreadPriority.Normal                         '优先级
            Thread_Num.Start()
    
            Sleep(1000)
    
            Thread_MyWorks = New Thread(AddressOf MyWorks)                      '新建线程 时间(横坐标)
            Thread_MyWorks.IsBackground = True                                  '设置为后台线程
            Thread_MyWorks.Priority = ThreadPriority.Highest                    '优先级
            Thread_MyWorks.Start()
    
            TextBox1.Text = "开始数据采集"
        End Sub
    
        Private Sub MyWorks()
            Interlocked.Exchange(Myworking, 1)
            'On Error Resume Next
            Mywork_Complete = False
            Do Until Mywork_Complete
    
                xh_RT += 1
    
                dt.Rows(xh_RT)(0) = Now
                dt.Rows(xh_RT)(1) = SP1_Num
    
                Sleep(1000)                                                 '延时
            Loop
            '
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Myworking, 0)
                Thread_MyWorks.Abort()
            Catch
                Thread_MyWorks = Nothing
            End Try
        End Sub
        Private Position_Monitoring, Myworking As Integer
    End Class

    效果图:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 O_lizhen 2021年1月17日 1:43
    2021年1月11日 9:48
    版主

全部回复

  • Hi O_lizhen,

    根据你的描述,你想要在datatable更新时实现刷新chart的功能。

    我用了一个button来模拟你的实时读取设备的事件,你可以相对应的发生改变。

    下面是具体的代码,你可以参考下。

     private void button1_Click(object sender, EventArgs e)
            {
                string name = textBox1.Text;
                int score = Convert.ToInt32(textBox2.Text);
                table.Rows.Add(name, score);
                table.AcceptChanges();
            }
            DataTable table = new DataTable();
            private void Form1_Load(object sender, EventArgs e)
            {
             
                table.Columns.Add("Name", typeof(string));
                table.Columns.Add("Score", typeof(int));
                table.Rows.Add("test1",23);
                table.Rows.Add("test2", 24);
                table.Rows.Add("test3", 25);
                chart1.Series.Clear();
                Series series1 = new Series();
                series1.Name = "series1";
                chart1.Series.Add(series1);
                chart1.Series["series1"].XValueMember = "Name";
                chart1.Series["series1"].YValueMembers = "Score";
                chart1.DataSource = table;
                table.RowChanged += Table_RowChanged;
            }
    
    
            private void Table_RowChanged(object sender, DataRowChangeEventArgs e)
            {
                    chart1.DataSource = table;
                    chart1.DataBind();
            }

    这是模拟的一个效果图:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 O_lizhen 2021年1月7日 2:13
    • 取消答案标记 O_lizhen 2021年1月9日 13:00
    2021年1月6日 9:47
    版主
  • 你好,感谢解答。
    谢谢
    2021年1月7日 3:01
  • 感谢您的回答。谢谢。
    之前语言描述的问题,有些表达不清晰的地方,未能完全表述我的意思,不好意思,先对其调整如下:

    需求:采集数据,并在chart图表中实时更新。采集数据:通过两个线程实现,时间线程(获取时间,作为横坐标),数据线程(获得数据,作为纵坐标),通过chart进行显示。

    问题: 在线程中,数据能够正常实现更新,chart不能实现刷新。

    相关代码:

    Imports System.Threading.Thread
    Imports System.Threading
    
    Public Class Form1
        Private xh_RT As Integer = -1                                           '数据行号
        Private dt As New DataTable
        Private SP1_Num As Single
        Private Thread_MyWorks, Thread_Num As System.Threading.Thread           '时间线程(横坐标),数据线程(纵坐标)
        Private Position_Monitor_Complete, Mywork_Complete As Boolean           '结束标志
        Private Position_Monitoring, Myworking As Integer
        Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    
            '设置数据线程
            dt.Columns.Add("tnow", Type.GetType("System.DateTime"))
            dt.Columns.Add("SP1", Type.GetType("System.Single"))
            For i = 0 To 1000                                                   '新建存储数据数据库
                dt.Rows.Add()
            Next
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 0
    
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 1
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 5
    
            Chart1.Series.Clear()                                               '清空
    
            Chart1.Series.Add(0)                                                '//添加
            Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Spline
            Chart1.Series(0).IsXValueIndexed = True
            Chart1.Series(0).XValueMember = "tnow"
            Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "dd-HH:mm"
            Chart1.Series(0).YValueMembers = "SP1"
            Chart1.Series(0).LegendText = "SP1"
            Chart1.Series(0).BorderColor = Color.FromArgb(185, 26, 59, 125)
    
            Chart1.DataSource = dt
            Chart1.DataBind()
    
            Thread_Num = New Thread(AddressOf Num_Monitor)                      '新建线程 数据(纵坐标)
            Thread_Num.IsBackground = True                                      '设置为后台线程
            Thread_Num.Priority = ThreadPriority.Normal                         '优先级
            Thread_Num.Start()
    
            Sleep(1000)
    
            Thread_MyWorks = New Thread(AddressOf MyWorks)                      '新建线程 时间(横坐标)
            Thread_MyWorks.IsBackground = True                                  '设置为后台线程
            Thread_MyWorks.Priority = ThreadPriority.Highest                    '优先级
            Thread_MyWorks.Start()
    
            TextBox1.Text = "开始数据采集"
        End Sub
    
        Private Sub Num_Monitor()
            Position_Monitor_Complete = False
            Threading.Interlocked.Exchange(Position_Monitoring, 1)
    
            Do Until Position_Monitor_Complete
                SP1_Num += 1
                Sleep(2000)
            Loop
    
    
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Position_Monitoring, 0)
                Thread_Num.Abort()
            Catch
                Thread_Num = Nothing
            End Try
        End Sub
    
        Private Sub MyWorks()
            Interlocked.Exchange(Myworking, 1)
            'On Error Resume Next
            Mywork_Complete = False
            Do Until Mywork_Complete
    
                xh_RT += 1
    
                dt.Rows(xh_RT)(0) = Now
                dt.Rows(xh_RT)(1) = SP1_Num
    
                Sleep(1000)                                                 '延时
            Loop
            '
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Myworking, 0)
                Thread_MyWorks.Abort()
            Catch
                Thread_MyWorks = Nothing
            End Try
        End Sub
    
        Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
    
            Position_Monitor_Complete = True
            Sleep(100)
            Mywork_Complete = True
    
            TextBox1.Text = "停止数据采集"
        End Sub
    End Class
    
    
    2021年1月9日 8:26
  • Hi O_lizhen,

    感谢您的反馈。

    根据我的测试,我建议你可以加一个timer控件,因为你把设置数据的过程全部写在了form_load事件中,这个事件只会触发一次,因此chart中的数据是不能更新的。

    你可以参考下面的代码:

    Public Class Form1
    
        Private xh_RT As Integer = -1                                           '数据行号
        Private dt As New DataTable
        Private SP1_Num As Single
        Private Thread_MyWorks, Thread_Num As System.Threading.Thread           '时间线程(横坐标),数据线程(纵坐标)
        Private Position_Monitor_Complete, Mywork_Complete As Boolean           '结束标志
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            '设置数据线程
            dt.Columns.Add("tnow", Type.GetType("System.DateTime"))
            dt.Columns.Add("SP1", Type.GetType("System.Single"))
            For i = 0 To 1000                                                   '新建存储数据数据库
                dt.Rows.Add()
            Next
            Timer1.Interval = 1000
            Timer1.Start()
    
        End Sub
        Private Sub Num_Monitor()
            Position_Monitor_Complete = False
            Threading.Interlocked.Exchange(Position_Monitoring, 1)
    
            Do Until Position_Monitor_Complete
                SP1_Num += 1
                Sleep(2000)
            Loop
    
    
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Position_Monitoring, 0)
                Thread_Num.Abort()
            Catch
                Thread_Num = Nothing
            End Try
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Position_Monitor_Complete = True
            Sleep(100)
            Mywork_Complete = True
    
            TextBox1.Text = "停止数据采集"
            Timer1.Stop()
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 0
    
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 1
            Sleep(1000)
    
            xh_RT += 1
            dt.Rows(xh_RT)(0) = Now
            dt.Rows(xh_RT)(1) = 5
    
            Chart1.Series.Clear()                                               '清空
    
            Chart1.Series.Add(0)                                                '//添加
            Chart1.Series(0).ChartType = DataVisualization.Charting.SeriesChartType.Spline
            Chart1.Series(0).IsXValueIndexed = True
            Chart1.Series(0).XValueMember = "tnow"
            Chart1.ChartAreas(0).AxisX.LabelStyle.Format = "dd-HH:mm"
            Chart1.Series(0).YValueMembers = "SP1"
            Chart1.Series(0).LegendText = "SP1"
            Chart1.Series(0).BorderColor = Color.FromArgb(185, 26, 59, 125)
    
            Chart1.DataSource = dt
            Chart1.DataBind()
    
            Thread_Num = New Thread(AddressOf Num_Monitor)                      '新建线程 数据(纵坐标)
            Thread_Num.IsBackground = True                                      '设置为后台线程
            Thread_Num.Priority = ThreadPriority.Normal                         '优先级
            Thread_Num.Start()
    
            Sleep(1000)
    
            Thread_MyWorks = New Thread(AddressOf MyWorks)                      '新建线程 时间(横坐标)
            Thread_MyWorks.IsBackground = True                                  '设置为后台线程
            Thread_MyWorks.Priority = ThreadPriority.Highest                    '优先级
            Thread_MyWorks.Start()
    
            TextBox1.Text = "开始数据采集"
        End Sub
    
        Private Sub MyWorks()
            Interlocked.Exchange(Myworking, 1)
            'On Error Resume Next
            Mywork_Complete = False
            Do Until Mywork_Complete
    
                xh_RT += 1
    
                dt.Rows(xh_RT)(0) = Now
                dt.Rows(xh_RT)(1) = SP1_Num
    
                Sleep(1000)                                                 '延时
            Loop
            '
            '停止监测线程
            Try
                Threading.Interlocked.Exchange(Myworking, 0)
                Thread_MyWorks.Abort()
            Catch
                Thread_MyWorks = Nothing
            End Try
        End Sub
        Private Position_Monitoring, Myworking As Integer
    End Class

    效果图:

    Best Regards,

    Jack


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    • 已标记为答案 O_lizhen 2021年1月17日 1:43
    2021年1月11日 9:48
    版主
  • 非常感谢,谢谢。
    2021年1月17日 1:44