如何使用此代码处理多线程 [英] How do I get this code to work with multi threading

查看:48
本文介绍了如何使用此代码处理多线程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为我们的仓库建立KPI评分板,我遇到了以下问题。

我有一个名为order tile的自定义控件,其代码如下:



I am building a KPI score board for our warehouse and i have run into the following issue.
I have a custom control called order tile that has the following code:

Public Class OrderTile



    Private _BorderBoxColor As Color
    Public Property BorderBoxColor() As Color
        Get
            Return _BorderBoxColor
        End Get
        Set
            _BorderBoxColor = Value
            ChangeBackColor_Threadsafe(_BorderBoxColor)
        End Set
    End Property
    Private _SaleOrder As String
    Public Property SalesOrder() As String
        Get
            Return _SaleOrder
        End Get
        Set
            _SaleOrder = Value
            UpdateText_Threadsafe(lblSODS, _SaleOrder)
        End Set
    End Property
    Private _Customer As String
    Public Property Customer() As String
        Get
            Return _Customer
        End Get
        Set
            _Customer = Value
            UpdateText_Threadsafe(lblCustomer, _Customer)
        End Set
    End Property
    Private _SalesValue As String
    Public Property SalesValue() As String
        Get
            Return _SalesValue
        End Get
        Set
            _SalesValue = Value
            UpdateText_Threadsafe(lblValue, _SalesValue)
        End Set
    End Property
    Private _CountdownTime As TimeSpan
    Public Property CountDownTime() As TimeSpan
        Get
            Return _CountdownTime
        End Get
        Set
            _CountdownTime = Value
            tmrCountdown.Interval = 500
            tmrCountdown.Start()

        End Set
    End Property
    Private _TargetDT As Date
    Public Property TargetDT() As Date
        Get
            Return _TargetDT
        End Get
        Set
            _TargetDT = Value

        End Set
    End Property
    Private _Flash As Boolean



    Public Property Flash() As Boolean
        Get
            Return _Flash
        End Get
        Set
            _Flash = Value
            If _Flash = False Then
                tmrFlashBorder.Stop()
                'Me.BackColor = _BorderBoxColor
                ChangeBackColor_Threadsafe(_BorderBoxColor)
            ElseIf _Flash = True Then
                tmrFlashBorder.Start()
            End If

        End Set
    End Property

    Private Sub tmrCountdown_Tick(sender As Object, e As EventArgs) Handles tmrCountdown.Tick
        Dim ts As TimeSpan = _TargetDT.Subtract(DateTime.Now)
        If ts.TotalMilliseconds > 0 Then
            'lblCountDownTimer.Text = ts.ToString("mm\:ss")
            UpdateText_Threadsafe(lblCountDownTimer, ts.ToString("mm\:ss"))
        Else
            'lblCountDownTimer.Text = "00:00"
            UpdateText_Threadsafe(lblCountDownTimer, "00:00")
            tmrCountdown.Stop()
        End If

    End Sub

    Private Sub tmrFlashBorder_Tick(sender As Object, e As EventArgs) Handles tmrFlashBorder.Tick
        If Me.BackColor = Color.White Then
            Me.BackColor = _BorderBoxColor

        ElseIf Me.BackColor = _BorderBoxColor Then
            Me.BackColor = Color.White

        End If

    End Sub
    Delegate Sub UpdateText_Delegate(ByVal Lable As DevExpress.XtraEditors.LabelControl, ByVal text As String)
    Private Sub UpdateText_Threadsafe(ByVal Lable As DevExpress.XtraEditors.LabelControl, ByVal text As String)
        If Lable.InvokeRequired Then
            Dim MyDelegate As New UpdateText_Delegate(AddressOf UpdateText_Threadsafe)
            Me.Invoke(MyDelegate, New Object() {Lable, text})
        Else
            Lable.Text = text
        End If
    End Sub

    Delegate Sub ChangeBackColor_Delegate(ByVal BackColor As Color)
    Private Sub ChangeBackColor_Threadsafe(ByVal BackColor As Color)
        If Me.InvokeRequired Then
            Dim MyDelegate As New ChangeBackColor_Delegate(AddressOf ChangeBackColor_Threadsafe)
            Me.Invoke(MyDelegate, New Object() {Me, BackColor})
        Else
            Me.BackColor = BackColor
        End If
    End Sub

End Class





这里是代码使用此控件。此代码是从BackGround Worker DoWork中调用的。





and here is the code that uses this Control. this code is call from within a BackGround Worker DoWork.

Private Sub DrawTiles()
     Dim XSpace = 368, YSpace = 120, XMax = 3, YMax = 4
     OrderTiles.DefaultView.Sort = "ID ASC"
     'grpOrderTiles.Controls.Clear()
     ClearTiles_Treadsafe(grpOrderTiles)
     Dim TC = 0
     Dim TileCount As Integer = OrderTiles.Rows.Count
     For i = 0 To TileCount - 1
             TC = i + 1


         Dim NewTile As New FDVICKPIScreenV4.OrderTile

             NewTile.Name = "OrderTile" & OrderTiles.Rows(i).Item(ColTileID).ToString
             NewTile.SalesOrder = OrderTiles.Rows(i).Item(ColTileSalesOrderNo).ToString
             NewTile.Customer = OrderTiles.Rows(i).Item(ColTileCustomer).ToString
             NewTile.SalesValue = OrderTiles.Rows(i).Item(ColTileSalesValue).ToString
             NewTile.BorderBoxColor = Color.FromName(OrderTiles.Rows(i).Item(ColTileBox).ToString)
             NewTile.CountDownTime = TimeSpan.FromMinutes(30)
             NewTile.Flash = OrderTiles.Rows(i).Item(ColTileFlash)
             NewTile.TargetDT = OrderTiles.Rows(i).Item(ColTileTargetDT)


             If TC = 1 Then
                 NewTile.Location = New Point(13, 34)
             ElseIf TC > 1 AndAlso TC <= 5 Then
                 NewTile.Location = New Point(13 + XSpace * i, 34) '34 + YSpace * i
             ElseIf TC > 5 AndAlso TC <= 10 Then
                 NewTile.Location = New Point(13 + XSpace * (i - 5), 154)
             ElseIf TC > 10 AndAlso TC <= 15 Then
                 NewTile.Location = New Point(13 + XSpace * (i - 10), 274)
             ElseIf TC > 15 AndAlso TC <= 20 Then
                 NewTile.Location = New Point(13 + XSpace * (i - 15), 394)
             End If

             AddTile_Treadsafe(grpOrderTiles, NewTile)

     Next

 End Sub





当我在同一个线程上调用它时,代码运行正常但是当我从BackGround调用它时当我得到Exception User-Unhandled System.NullReferenceException:'对象引用没有设置为对象的实例。'时,



The code runs fine when i call it all on the same thread but when i call it from the BackGround Worker that is when I get "Exception User-Unhandled System.NullReferenceException: 'Object reference not set to an instance of an object.' on the

Dim NewTile As FDVICKPIScreenV4.OrderTile

在DrawTiles Sub中。



我尝试了什么:



我试图实现SyncLock但是我们已经能够实现这一点。我只是不太了解多线程来解决这个问题。



非常感谢所有帮助。

in the DrawTiles Sub.

What I have tried:

I have tried to implement SyncLock but haven been able to get this to work. I just don't know enough about multi threading to resolve this one.

All help is very appreciated.

推荐答案

您滥用了BackgroundWorker的UI报告功能;你应该使用ReportProgress方法和相关的事件处理程序:



BackgroundWorker.ReportProgress方法(System.ComponentModel) [ ^ ]
You've misused the BackgroundWorker's "UI reporting" capabilities; you should be using the "ReportProgress" method and associated event handler:

BackgroundWorker.ReportProgress Method (System.ComponentModel)[^]


这篇关于如何使用此代码处理多线程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆