更新时DatagridView崩溃导致滚动条出现

时间:2012-11-07 10:11:49

标签: vb.net multithreading datagridview

我的vb.net 4.0项目是内部交易平台。

名为 MsgPad 的单独表单包含名为 MsgPadDG 的Datagridview。

表单加载子做两件事:格式化datagridview并为gridview刷新定义一个计时器。

第二个Sub UpdateMyMsg ,通过 NewMessage 事件从线程 UIUpdaterEngine 接收更新,并更新 MyMessages < / strong>对象(基本上是数据表)。

第三个子 UpdateMdgPadDGW ,使用invoke方法更新/刷新datagridview(可能没有必要,因为计时器是在UI线程中定义的。)

最后,Datagridview属性:行定义为非用户可编辑 AutoSizeRowsMo​​de = Displayedcells ScrollBars = Both

我的问题是,当更新过程添加超出datagridview限制的行时,整个应用程序崩溃,导致滚动条出现。 我尝试了没有计时器(直接在UpdateMyMsg Sub中调用数据源更新)和计时器,但问题始终存在。 奇怪的是: Try-Catch 块没有捕捉到任何东西。

提前感谢您的重播。

爱德华多

这里是代码:

Public Class MsgPad
Private WithEvents _MyUIUpdaterEngine As MyUIUpdaterEngine = MyUIUpdaterEngine.Instance
Private MyMessages As New Messages
Private LastUpdate As DateTime = TimeValue("08:00:00")
Private ObjLock As New Object
Private NewMessages As Boolean = False
Dim UpdateDGWTimer As New System.Timers.Timer

 Private Sub MsgPad_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
    Try
        '--
        MsgPadDG.DataSource = MyMessages.DTable
        '--
        With MsgPadDG
            '--
            .Columns("Msg_ID").Visible = False
            .Columns("I_CommandID").Visible = False
            .Columns("B_ID").Visible = False
            .Columns("F_ID").Visible = False
            .Columns("T_TV").Visible = False
            .Columns("T_Sign").Visible = False
            .Columns("T_Mde").Visible = False
            .Columns("T_QU").Visible = False
            .Columns("T_QI").Visible = False
            .Columns("T_QF").Visible = False
            .Columns("T_PI").Visible = False
            .Columns("T_PF").Visible = False
            '--
            .Columns("Msg_RecDate").HeaderText = "Date"
            .Columns("Msg_RecDate").Width = 50
            .Columns("Msg_RecDate").DefaultCellStyle.Format = "HH:mm:ss"
            .Columns("I_Symbol").HeaderText = "Symbol"
            .Columns("I_Symbol").Width = 80
            .Columns("I_Des").HeaderText = "Des"
            .Columns("I_Des").Width = 180
            .Columns("Msg_Text").HeaderText = "Message"
            .Columns("Msg_Text").Width = 250
            '--

        End With

        '--Crea timer per l'Update del DAtagridView
        AddHandler UpdateDGWTimer.Elapsed, AddressOf UpdateMsgPadDGW
        UpdateDGWTimer.Interval = 3500
        UpdateDGWTimer.Enabled = True
 .....
 .....
 End Sub

 Private Sub UpdateMyMsg(ByVal CRec As OrderRecord, ByVal Msg As String) Handles _MyUIUpdaterEngine.NewMessage

    Try
        SyncLock ObjLock
            '--Aggiorna la tabella MyMessages
            MyMessages.Add(CRec, Msg)
            NewMessages = True
            '--Parla messaggio
            Dim synth As New SpeechSynthesizer
            Dim TalkMsg As String = Msg
            If CRec.I_Des <> Nothing Then TalkMsg += " su: " + CRec.I_Des
            synth.SpeakAsync(TalkMsg)
        End SyncLock
 .....
 .....
 End Sub


 Private Sub UpdateMsgPadDGW(source As Object, e As ElapsedEventArgs)

    '--Aggiorna MesssagePad
    Try
        SyncLock ObjLock
            If NewMessages Then
                MsgPadDG.ControlInvoke(Sub(l)
                                           MsgPadDG.DataSource = MyMessages.DTable
                                           MsgPadDG.Refresh()
                                           MsgPadDG.ClearSelection()
                                       End Sub)
                NewMessages = False
            End If
        End SyncLock
 .....
 .....
 End Sub

1 个答案:

答案 0 :(得分:1)

        '--Aggiorna la tabella MyMessages
        MyMessages.Add(CRec, Msg)
        NewMessages = True

这是一个致命的错误,DGV与MyMessages绑定。因此,在工作线程中调用Add()会导致控件从错误的线程更新。您通常会从错误的线程访问控件时遇到IllegalOperationException,但遗憾的是,这对于绑定数据不起作用。

您需要以不同方式执行此操作,让工作人员将消息添加到List。然后在调用的代码中使用这些新消息更新MyMessages。

另请注意,您的计时器是您在问题中假设的安全计时器。只有一个System.Windows.Forms.Timer是一个安全的,它的Tick事件处理程序将在UI线程上运行。然后你也不需要再调用了。