如何使函数与Control.CheckForIllegalCrossThreadCalls一起使用

时间:2019-06-11 19:57:42

标签: vb.net

当我评论Control.CheckForIllegalCrossThreadCalls = False时,我的函数可以正常工作,但未注释时会出现错误

我正在使用BackgroundWorker调用一个将值插入数据库的函数,并且我需要设置Control.CheckForIllegalCrossThreadCalls = False才能使代码正常工作。现在,当我将其设置为false时,其中一个功能无法正常工作。这是错误

  

从字符串“ -0-1-22”到“日期”类型的转换无效”

当该功能正常工作时

Private Sub btnUpload_Click(sender As Object, e As EventArgs) Handles btnUpload.Click

    If Not BackgroundWorker1.IsBusy = True Then
        BackgroundWorker1.RunWorkerAsync()
    End If

End Sub

我希望该函数附带“ 2019-06-11”作为要插入数据库的日期,而无需使用Control.CheckForIllegalCrossThreadCalls = False

这是代码

Private Sub BackgroundWorker1_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
    count_rows()
End Sub

Private Sub BackgroundWorker1_RunWorkerCompleted(sender As Object, e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
    MsgBox("Products imported successfully!", MsgBoxStyle.Information, "Import")
    Me.Close()
End Sub
Public Sub count_rows()
    import_attendance_sheet(1054)
End Sub
Private Sub import_attendance_sheet(ByVal id As Integer)
    ProgressBar1.Minimum = 0
    ProgressBar1.Maximum = id
    ProgressBar1.Value = 0
    Dim path As String = txtPath.Text
    Dim excel_connection As OleDbConnection
    Dim dt As DataTable
    Dim cmd As OleDbDataAdapter
    'Dim sql As String
    'Dim result As Boolean
    Dim emp_type_id As String = ""
    Dim branch_id As String = ""
    Dim bank_id As String = ""
    'Dim sheet_dates As New List(Of String)
    'excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + path + ";Extended Properties=Excel 12.0 Xml; HDR=Yes;")
    excel_connection = New OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";Extended Properties='Excel 12.0 Xml;HDR=No;IMEX=1;';")
    cmd = New OleDbDataAdapter("SELECT * FROM [sheet$]", excel_connection)
    dt = New DataTable
    cmd.Fill(dt)
    'initialize symbol row
    Dim count As Integer = 6
    'Loop through dates(column/header)
    For Each column As DataColumn In dt.Columns
        Dim colum_name As String = dt.Rows(0)(column.ColumnName).ToString()
        'check if column cell is empty
        If colum_name = "" Then
            'Empty do nothing
        Else
            'increment symbol row by 1
            count = count + 1
            'MsgBox(count)
            'Loop through rows of a particular date/column/header
            For Each r As DataRow In dt.Rows
                'check row(empNo) cell is not empty & does not have a string
                If r(5).ToString() = "" Or r(5).ToString() = "COY #" Then
                    'Empty do nothing
                Else
                    'show date | Emp No | Name | symbol index
                    'MsgBox(colum_name & " " & r(5).ToString() & " " & r(6).ToString() & " " & r(count).ToString())
                    'do the calculation
                    Dim employ_id As String = get_employee_id(r(5).ToString)
                    Dim basic_salary As Decimal = get_employee_basic_salary(r(5).ToString)
                    Dim staff_type_id As String = get_employee_type_id(r(5).ToString)
                    Dim days_per_month As Integer = get_employee_days_per_month(staff_type_id)
                    Dim hours_per_day As Double = get_employee_hours_per_day(staff_type_id)
                    Dim hourly_rate As Double = basic_salary / days_per_month / hours_per_day
                    Dim daily_rate As Double = basic_salary / days_per_month
                    Dim normal_working_hrs As String = get_normal_working_hrs()
                    Dim shift_duration As String = get_shift_duration()
                    'get symbol id and its rate
                    Dim symbol_id As String = get_attendance_symbol_id(r(count).ToString)
                    Dim symbol_rate As Double = get_attendance_symbol_rate(symbol_id)
                    Dim symbol_deduction_status As String = get_symbol_deduction_status(symbol_id)
                    Dim td_amount As Double = 0
                    If symbol_deduction_status = "DEDUCT" Then
                        td_amount = hourly_rate
                    Else
                        td_amount = 0
                    End If
                    Dim overtime As Double = shift_duration - normal_working_hrs
                    Dim ot_amount As Double = overtime * hourly_rate * symbol_rate
                    Dim chaka As String = Date.Now.ToString("yyyy")
                    Dim tsiku As String = Date.Now.ToString("dd")
                    Dim tsiku_mawu As String = Date.Now.ToString("dddd")
                    Dim mwezi As String = Date.Now.ToString("MMMM")
                    ' ''insert values into DB
                    Sql = "INSERT INTO tbl_attendance (employee_id,time_in,time_out,total_hours_worked,overtime,ot_amount,td_amount,attendance_code_id,attendance_code,attendance_date,comment,year,date,day,month,hourly_rate,bsalary,ot_status) VALUES ('" & employ_id & "','" & 0 & "','" & 0 & "','" & shift_duration & "','" & overtime & "','" & ot_amount & "','" & td_amount & "','" & symbol_id & "','" & r(count).ToString & "','" & calc_attendance_date(colum_name) & "','import','" & chaka & "','" & tsiku & "','" & tsiku_mawu & "','" & mwezi & "','" & hourly_rate & "','" & basic_salary & "','" & symbol_rate & "')"
                    result = save_to_db(Sql)
                    ProgressBar1.Value = ProgressBar1.Value + 1
                    'If result Then
                    '    Timer1.Start()
                    'End If
                End If
            Next
        End If
    Next
End Sub
'******* Function which shows the error ****************
Public Function calc_attendance_date(ByVal value As String)
    Dim at_date As String = ""
    Dim current_month As String = frmMain.cmbMonth.Text
    Dim current_year As String = frmMain.cmbYear.Text
    Dim mwezi As String
    Dim chaka As String
    Dim format_day As String = ""
    Dim format_month As String = ""
    'Date.Now.ToString("yyyy-MM-dd")
    '****  find previous month
    'when its january
    If current_month = "January" And value >= 22 And value <= 31 Then
        mwezi = "12"
        chaka = Convert.ToInt32(current_year) - 1
        at_date = chaka & "-" & mwezi & "-" & value
    ElseIf current_month <> "January" And value >= 22 And value <= 31 Then
        mwezi = IntMonth() - 1
        'day
        If value < 10 Then
            format_day = "0" & value
        ElseIf value >= 10 Then
            format_day = value
        End If
        'format mwezi
        If mwezi < 10 Then
            format_month = "0" & mwezi
        ElseIf mwezi >= 10 Then
            format_month = mwezi
        End If
        chaka = current_year
        at_date = chaka & "-" & format_month & "-" & format_day
    End If
    '****  find current month
    If current_month = "January" And value >= 1 And value <= 21 Then
        mwezi = IntMonth()
        chaka = current_year
        'day
        If value < 10 Then
            format_day = "0" & value
        ElseIf value >= 10 Then
            format_day = value
        End If
        'format mwezi
        If mwezi < 10 Then
            format_month = "0" & mwezi
        ElseIf mwezi >= 10 Then
            format_month = mwezi
        End If
        at_date = chaka & "-" & format_month & "-" & format_day
    ElseIf current_month <> "January" And value >= 1 And value <= 21 Then
        mwezi = IntMonth()
        chaka = current_year
        'day
        If value < 10 Then
            format_day = "0" & value
        ElseIf value >= 10 Then
            format_day = value
        End If
        'format mwezi
        If mwezi < 10 Then
            format_month = "0" & mwezi
        ElseIf mwezi >= 10 Then
            format_month = mwezi
        End If
        at_date = chaka & "-" & format_month & "-" & format_day
    End If
    Return at_date
End Function

1 个答案:

答案 0 :(得分:0)

您不应尝试通过非UI线程与UI控件进行交互。但是,您可以使用Control.Invoke使代码与UI线程上的那些控件进行交互。在一些地方可以做到这一点。

import_attendance_sheet

ProgressBar1.Minimum = 0
ProgressBar1.Maximum = id
ProgressBar1.Value = 0
Dim path As String = txtPath.Text
...
ProgressBar1.Value = ProgressBar1.Value + 1

相反:

Dim path As String
Me.Invoke(
    Sub()
        ProgressBar1.Minimum = 0
        ProgressBar1.Maximum = id
        ProgressBar1.Value = 0
        path = txtPath.Text
    End Sub)
...
Me.Invoke(Sub() ProgressBar1.Value += 1)

所有类似get_employee_idget_employee_basic_salaryget_employee_type_id之类的功能也可能与UI交互,但是您不提供它们。如果这样做(即从文本框或其他内容返回值),则还需要在它们内部调用。

calc_attendance_date

Dim current_month As String = frmMain.cmbMonth.Text
Dim current_year As String = frmMain.cmbYear.Text

相反:

Dim current_month As String 
Dim current_year As String 
Me.Invoke(
    Sub()
        current_month = frmMain.cmbMonth.Text
        current_year = frmMain.cmbYear.Text
    End Sub)

函数IntMonth()对我们也是未知的。同样,如果它从UI读取,则应调用进行UI交互的代码。

仅当绝对必要时(即Control.InvokeRequired时)才调用此方法。请参阅this example,因为他们想使用Me.CheckForIllegalCrossThreadCalls = False(不好!)

更好的是,您可以编写extension methods来自动化Control.InvokeRequired模式