Expiring Today—Celebrate National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

vb.net background worker crossthread

Posted on 2017-04-13
11
Medium Priority
?
83 Views
Last Modified: 2017-04-14
I have the following that I want to be done as a background process. it fails with crossthread error understandably  on the
  StrTemp = CBList.Text

Open in new window


I know why as the cblist is part of the GUI and the background process is not but I dont know how to get around that. ive used the background worker in another part of the program but that's fine as it doesnt rely on a value from a cb whereas this does.

the background task
 Private Sub CBList_SelectedIndexChanged(sender As Object, e As EventArgs) Handles CBList.SelectedIndexChanged
        'adds common word selected to link table
        Dim deletions As New List(Of String)
        Dim StrCommonSet As Boolean
        Dim StrTemp As String
        StrTemp = ""
        Dim y As Integer
        StrCommonSet = False

        If OPBulkDescView4.Checked = True Then
            Using cnSql As New SqlClient.SqlConnection("Data Source=MAIN-PC\SQLEXPRESS;Initial Catalog=Dictionary;Integrated Security=True;MultipleActiveResultSets=True")
                cnSql.Open()
                y = DataGridViewStringsBulk.RowCount
                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If Not Convert.IsDBNull(row.Cells("StrCommon").Value) Then

                        If Not deletions.Contains(row.Cells("StrCommon").Value, StringComparer.OrdinalIgnoreCase) Then
                            deletions.Add(row.Cells("StrCommon").Value)
                        End If

                    End If
                Next

                For Each term In deletions
                    Using cmdInsert As New SqlCommand("usp_DeleteShortDescLinkWords", cnSql)
                        cmdInsert.CommandType = CommandType.StoredProcedure
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.Parameters.AddWithValue("@Word", term)
                        cmdInsert.ExecuteScalar()
                    End Using
                Next

                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If StrCommonSet = False Then
                        StrTemp = CBList.Text
                        StrCommonSet = True
                    End If

                    Using cmdInsert As New SqlClient.SqlCommand
                        cmdInsert.Connection = cnSql
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.CommandText = "INSERT INTO TblShortDescLink (StrShort, StrCommon) VALUES ('" & row.Cells("Strshort").Value & "','" & StrTemp & "'" & ")"
                        cmdInsert.ExecuteNonQuery()
                    End Using
                Next
                Using cmdCommonInsert As New SqlCommand("usp_UpdateStrCommon", cnSql)
                    cmdCommonInsert.CommandType = CommandType.StoredProcedure
                    cmdCommonInsert.CommandTimeout = 0
                    cmdCommonInsert.ExecuteNonQuery()
                End Using
            End Using

            'MessageBox.Show("Linking finished")
        Else
            'MessageBox.Show("StrShort must be checked in order to link succesfully")
        End If
    End Sub

Open in new window


background worker 3 code
    Private Sub startAsyncButton3_Click(ByVal sender As System.Object,
    ByVal e3 As System.EventArgs) Handles CBList.SelectedIndexChanged


        If BackgroundWorker3.IsBusy <> True Then
            ' Start the asynchronous operation.

            Me.ResultLabelLink.Visible = True
            Me.ResultLabelLink.Text = "Processing Link Words"
            Me.ProgressBar4.Visible = True
            Me.ProgressBar4.Enabled = True
            'Me.CBList.Enabled = False

            'Me.StrShortCancel.Enabled = True

            BackgroundWorker3.RunWorkerAsync()
        End If
    End Sub


    Private Sub backgroundWorker3_DoWork(ByVal sender As System.Object,
    ByVal e3 As DoWorkEventArgs) Handles BackgroundWorker3.DoWork
        Dim worker3 As BackgroundWorker = CType(sender, BackgroundWorker)

        ' Perform a time consuming operation and report progress.
        'worker3.ReportProgress(30)


    End Sub

    Private Sub backgroundWorker3_ProgressChanged(ByVal sender As System.Object,
    ByVal e3 As ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged

        'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
        Me.ProgressBar4.Enabled = True
        Me.ProgressBar4.Visible = True

    End Sub


    Private Sub backgroundWorker3_RunWorkerCompleted(ByVal sender As System.Object,
    ByVal e3 As RunWorkerCompletedEventArgs) Handles BackgroundWorker3.RunWorkerCompleted


        If e3.Cancelled = True Then
            ResultLabelLink.Text = "Canceled!"

        ElseIf e3.Error IsNot Nothing Then
            ResultLabelLink.Text = "Error: " & e3.Error.Message
        Else

            DataGroupCallStringsBulk()

            Me.ProgressBar4.Enabled = False
            Me.ProgressBar4.Visible = False
            Me.CBList.Enabled = True

            ResultLabelLink.Visible = False
            DataGridViewStringsBulk.Refresh()

        End If
    End Sub

Open in new window

0
Comment
Question by:PeterBaileyUk
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 3
  • 3
11 Comments
 
LVL 34

Expert Comment

by:it_saige
ID: 42091780
Just to clarify, you want the selected index code to be a part of the background worker do work method?

-saige-
0
 

Author Comment

by:PeterBaileyUk
ID: 42091819
yes this:

 'adds common word selected to link table
        Dim deletions As New List(Of String)
        Dim StrCommonSet As Boolean
        Dim StrTemp As String
        StrTemp = ""
        Dim y As Integer
        StrCommonSet = False

        If OPBulkDescView4.Checked = True Then
            Using cnSql As New SqlClient.SqlConnection("Data Source=MAIN-PC\SQLEXPRESS;Initial Catalog=Dictionary;Integrated Security=True;MultipleActiveResultSets=True")
                cnSql.Open()
                y = DataGridViewStringsBulk.RowCount
                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If Not Convert.IsDBNull(row.Cells("StrCommon").Value) Then

                        If Not deletions.Contains(row.Cells("StrCommon").Value, StringComparer.OrdinalIgnoreCase) Then
                            deletions.Add(row.Cells("StrCommon").Value)
                        End If

                    End If
                Next

                For Each term In deletions
                    Using cmdInsert As New SqlCommand("usp_DeleteShortDescLinkWords", cnSql)
                        cmdInsert.CommandType = CommandType.StoredProcedure
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.Parameters.AddWithValue("@Word", term)
                        cmdInsert.ExecuteScalar()
                    End Using
                Next

                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If StrCommonSet = False Then
                        StrTemp = CBList.Text
                        StrCommonSet = True
                    End If

                    Using cmdInsert As New SqlClient.SqlCommand
                        cmdInsert.Connection = cnSql
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.CommandText = "INSERT INTO TblShortDescLink (StrShort, StrCommon) VALUES ('" & row.Cells("Strshort").Value & "','" & StrTemp & "'" & ")"
                        cmdInsert.ExecuteNonQuery()
                    End Using
                Next
                Using cmdCommonInsert As New SqlCommand("usp_UpdateStrCommon", cnSql)
                    cmdCommonInsert.CommandType = CommandType.StoredProcedure
                    cmdCommonInsert.CommandTimeout = 0
                    cmdCommonInsert.ExecuteNonQuery()
                End Using
            End Using

            'MessageBox.Show("Linking finished")
        Else
            'MessageBox.Show("StrShort must be checked in order to link succesfully")
        End If

Open in new window

0
 
LVL 13

Expert Comment

by:ktaczala
ID: 42091904
Change this section:
If StrCommonSet = False Then
'StrTemp = CBList.Text
StrTemp = bg_GetCBlistText
StrCommonSet = True
End If

Open in new window


Add this function outside of the Background Job
Private Delegate Function bg_GetCBListTextInvoker()
    Private Function bg_GetCBListText()
        If Me.CBList.InvokeRequired Then
            Me.CBList.Invoke(New bg_GetCBListTextInvoker(AddressOf bg_GetCBListText))
            Return CBList.Text
        Else
            Return CBList.Text
        End If
    End Function

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 34

Expert Comment

by:it_saige
ID: 42091976
Normally I would say that you want to send the text as a parameter to the worker, but it appears as you need to actually send more than this, you also have other controls in this method (OPBulkDescView4 and DataGridViewStringBulk).  As you are only viewing these then you could still use a parameter list; e.g. (untested) -
Private Sub startAsyncButton3_Click(ByVal sender As Object, ByVal e3 As EventArgs) Handles CBList.SelectedIndexChanged
    If BackgroundWorker3.IsBusy <> True Then
        ' Start the asynchronous operation.

        Me.ResultLabelLink.Visible = True
        Me.ResultLabelLink.Text = "Processing Link Words"
        Me.ProgressBar4.Visible = True
        Me.ProgressBar4.Enabled = True
        'Me.CBList.Enabled = False

        'Me.StrShortCancel.Enabled = True

        BackgroundWorker3.RunWorkerAsync(New With {CBList.Text, OPBulkDescView4.Checked, DataGridViewStringsBulk.RowCount, .SelectedRows = New List(Of DataGridViewRow)(DataGridViewStringsBulk.SelectedRows.Cast(Of DataGridViewRow)})
    End If
End Sub


Private Sub backgroundWorker3_DoWork(ByVal sender As Object, ByVal e3 As DoWorkEventArgs) Handles BackgroundWorker3.DoWork
    Dim worker = DirectCast(sender, BackgroundWorker)
    Dim deletions As New List(Of String)
    Dim StrCommonSet As Boolean
    Dim StrTemp As String = ""
    Dim Viewed As Boolean = False
    Dim RowCount As Integer = 0
    Dim SelectedRows As New List(Of DataGridViewRow)()
    Dim y As Integer
    If e3.Argument IsNot Nothing Then
        StrTemp = If(e3.Argument(0) IsNot Nothing, Convert.ToString(e3.Argument(0)), "")
        Viewed = If(e3.Argument(1) IsNot Nothing, Convert.ToBoolean(e3.Argument(1)), False)
        RowCount = If(e3.Argument(2) IsNot Nothing, Convert.ToInt64(e3.Argument(2)), 0)
        SelectedRows = If(e3.Argument(3) IsNot Nothing, DirectCast(e3.Argument(3), List(Of DataGridViewRow)), Nothing)
    End If
    'adds common word selected to link table
    StrCommonSet = False

    If Viewed Then
        Using cnSql As New SqlClient.SqlConnection("Data Source=MAIN-PC\SQLEXPRESS;Initial Catalog=Dictionary;Integrated Security=True;MultipleActiveResultSets=True")
            cnSql.Open()
            y = RowCount
            For Each row In SelectedRows
                If Not Convert.IsDBNull(row.Cells("StrCommon").Value) Then
                    If Not deletions.Contains(row.Cells("StrCommon").Value, StringComparer.OrdinalIgnoreCase) Then
                        deletions.Add(row.Cells("StrCommon").Value)
                    End If

                End If
            Next

            For Each term In deletions
                Using cmdInsert As New SqlCommand("usp_DeleteShortDescLinkWords", cnSql)
                    cmdInsert.CommandType = CommandType.StoredProcedure
                    cmdInsert.CommandTimeout = 0
                    cmdInsert.Parameters.AddWithValue("@Word", term)
                    cmdInsert.ExecuteScalar()
                End Using
            Next

            For Each row In SelectedRows
                If StrCommonSet = False Then
                    StrCommonSet = True
                End If

                Using cmdInsert As New SqlClient.SqlCommand
                    cmdInsert.Connection = cnSql
                    cmdInsert.CommandTimeout = 0
                    cmdInsert.CommandText = "INSERT INTO TblShortDescLink (StrShort, StrCommon) VALUES ('" & row.Cells("Strshort").Value & "','" & StrTemp & "'" & ")"
                    cmdInsert.ExecuteNonQuery()
                End Using
            Next
            Using cmdCommonInsert As New SqlCommand("usp_UpdateStrCommon", cnSql)
                cmdCommonInsert.CommandType = CommandType.StoredProcedure
                cmdCommonInsert.CommandTimeout = 0
                cmdCommonInsert.ExecuteNonQuery()
            End Using
        End Using

        'MessageBox.Show("Linking finished")
    Else
        'MessageBox.Show("StrShort must be checked in order to link succesfully")
    End If
End Sub

Private Sub backgroundWorker3_ProgressChanged(ByVal sender As Object, ByVal e3 As ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged

    'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
    Me.ProgressBar4.Enabled = True
    Me.ProgressBar4.Visible = True

End Sub


Private Sub backgroundWorker3_RunWorkerCompleted(ByVal sender As Object, ByVal e3 As RunWorkerCompletedEventArgs) Handles BackgroundWorker3.RunWorkerCompleted


    If e3.Cancelled = True Then
        ResultLabelLink.Text = "Canceled!"

    ElseIf e3.Error IsNot Nothing Then
        ResultLabelLink.Text = "Error: " & e3.Error.Message
    Else

        DataGroupCallStringsBulk()

        Me.ProgressBar4.Enabled = False
        Me.ProgressBar4.Visible = False
        Me.CBList.Enabled = True

        ResultLabelLink.Visible = False
        DataGridViewStringsBulk.Refresh()

    End If
End Sub

Open in new window


-saige-
0
 

Author Comment

by:PeterBaileyUk
ID: 42092130
ok I started with ktaczala's solution which compiled but gave the cross thread message in the first part of the function, I tried IT saige's solution too and that gave syntax errors on

(DataGridViewStringsBulk.SelectedRows.Cast(Of DataGridViewRow)})

Open in new window

IT Saige syntax here


ktaczala's  failed here
Me.CBList.Invoke(New bg_GetCBListTextInvoker(AddressOf bg_GetCBListText))
            Return CBList.Text

Open in new window

failed here



Imports System
Imports System.Text.RegularExpressions
Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration
Imports System.Runtime.CompilerServices
Imports System.ComponentModel

Public Class Form1

    Dim AllListBox As New List(Of ListBox)()
    Private dtWords As DataTable

    'Private backgroundWorker1 As BackgroundWorker = New BackgroundWorker
    Public Sub New()
        InitializeComponent()

        BackgroundWorker1.WorkerReportsProgress = True
        BackgroundWorker1.WorkerSupportsCancellation = False
        BackgroundWorker2.WorkerReportsProgress = True
        BackgroundWorker2.WorkerSupportsCancellation = False
        BackgroundWorker3.WorkerReportsProgress = True
        BackgroundWorker3.WorkerSupportsCancellation = False
    End Sub

    Public Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        'StrShortCancel.Visible = False
        IsLoading = True

        Dim ctrl As Control = TabControl1
        'Me.StrShortCancel.Enabled = False
        ProgressBar2.Visible = False
        ProgressBar2.Enabled = False
        ProgressBar3.Visible = False
        ProgressBar3.Enabled = False
        ProgressBar4.Visible = False
        ProgressBar4.Enabled = False
        ResultLabel.Visible = False
        ResultLabelTag.Visible = False
        ResultLabelLink.Visible = False
        AllToolStripMenuItem.Checked = True
        CarsToolStripMenuItem.Checked = False
        MotorCyclesToolStripMenuItem.Checked = False
        LcvToolStripMenuItem.Checked = False
        OthersToolStripMenuItem.Checked = False
        CarLcvOtherToolStripMenuItem.Checked = False
        BikesQuadsToolStripMenuItem.Checked = False
        OPBulkDescView4.Checked = True
        StrShortStrTagClientVehTypeToolStripMenuItem.Checked = True
        OpBulkAllStrShort.Checked = True
        AllStrShortGroupsToolStripMenuItem.Checked = True
        OpShortDescAllAll.Checked = True
        AllToolStripMenuItem.Checked = True

        OpCreateStrWholeDb.Checked = True
        'WholeDBToolStripMenuItem.Checked = True
        OpBulkTag.Checked = True
        TagWordsToolStripMenuItem1.Checked = True
        OPIndividual.Checked = True
        IndividualToolStripMenuItem.Checked = True


        Me.TabControl1.SelectedTab = Me.TabPage6
        'populate right hand grid
        Call DataGroupCallStrCommon()
        IsLoading = False
        'only needed if start method 1

    End Sub
    Private Delegate Function bg_GetCBListTextInvoker()
    Private Function bg_GetCBListText()
        If Me.CBList.InvokeRequired Then
            Me.CBList.Invoke(New bg_GetCBListTextInvoker(AddressOf bg_GetCBListText))
            Return CBList.Text
        Else
            Return CBList.Text
        End If
    End Function
    Private Sub startAsyncButton_Click(ByVal sender As System.Object,
    ByVal e As System.EventArgs) Handles CreateShortStringsToolStripMenuItem.Click
        If BackgroundWorker1.IsBusy <> True Then
            ' Start the asynchronous operation.
            Me.ResultLabel.Visible = True
            Me.ResultLabel.Text = "Processing StrShort Strings"
            Me.ProgressBar2.Visible = True
            Me.ProgressBar2.Enabled = True
            Me.Panel1.Enabled = False
            Me.PanelBtnBulkTag.Enabled = False
            'Me.StrShortCancel.Enabled = True
            BackgroundWorker1.RunWorkerAsync()
        End If
    End Sub
    Private Sub startAsyncButton2_Click(ByVal sender As System.Object,
    ByVal e2 As System.EventArgs) Handles PanelBtnBulkTag.Click


        If BackgroundWorker2.IsBusy <> True Then
            ' Start the asynchronous operation.
            Me.ResultLabelTag.Visible = True
            Me.ResultLabelTag.Text = "Processing Tag Words"
            Me.ProgressBar3.Visible = True
            Me.ProgressBar3.Enabled = True
            Me.PanelBtnBulkTag.Enabled = False
            Me.Panel1.Enabled = False
            'Me.StrShortCancel.Enabled = True
            BackgroundWorker2.RunWorkerAsync()
        End If
    End Sub
    Private Sub startAsyncButton3_Click(ByVal sender As System.Object,
    ByVal e3 As System.EventArgs) Handles CBList.SelectedIndexChanged


        If BackgroundWorker3.IsBusy <> True Then
            ' Start the asynchronous operation.

            Me.ResultLabelLink.Visible = True
            Me.ResultLabelLink.Text = "Processing Link Words"
            Me.ProgressBar4.Visible = True
            Me.ProgressBar4.Enabled = True
            'Me.CBList.Enabled = False

            'Me.StrShortCancel.Enabled = True

            BackgroundWorker3.RunWorkerAsync()
        End If
    End Sub

    'This Event handler() Is where the time-consuming work Is done.
    Private Sub backgroundWorker1_DoWork(ByVal sender As System.Object,
    ByVal e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim worker As BackgroundWorker = CType(sender, BackgroundWorker)

        ' Perform a time consuming operation and report progress.
        'worker.ReportProgress(30)
        Call CreateAllStrs()

    End Sub
    Private Sub backgroundWorker2_DoWork(ByVal sender As System.Object,
    ByVal e2 As DoWorkEventArgs) Handles BackgroundWorker2.DoWork
        Dim worker2 As BackgroundWorker = CType(sender, BackgroundWorker)

        ' Perform a time consuming operation and report progress.
        'worker.ReportProgress(30)

        Call TagBulkWords()

    End Sub

    Private Sub backgroundWorker3_DoWork(ByVal sender As System.Object,
    ByVal e3 As DoWorkEventArgs) Handles BackgroundWorker3.DoWork
        Dim worker3 As BackgroundWorker = CType(sender, BackgroundWorker)

        ' Perform a time consuming operation and report progress.
        'worker3.ReportProgress(30)
        'adds common word selected to link table
        Dim deletions As New List(Of String)
        Dim StrCommonSet As Boolean
        Dim StrTemp As String
        StrTemp = ""
        Dim y As Integer
        StrCommonSet = False

        If OPBulkDescView4.Checked = True Then
            Using cnSql As New SqlClient.SqlConnection("Data Source=MAIN-PC\SQLEXPRESS;Initial Catalog=Dictionary;Integrated Security=True;MultipleActiveResultSets=True")
                cnSql.Open()
                y = DataGridViewStringsBulk.RowCount
                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If Not Convert.IsDBNull(row.Cells("StrCommon").Value) Then

                        If Not deletions.Contains(row.Cells("StrCommon").Value, StringComparer.OrdinalIgnoreCase) Then
                            deletions.Add(row.Cells("StrCommon").Value)
                        End If

                    End If
                Next

                For Each term In deletions
                    Using cmdInsert As New SqlCommand("usp_DeleteShortDescLinkWords", cnSql)
                        cmdInsert.CommandType = CommandType.StoredProcedure
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.Parameters.AddWithValue("@Word", term)
                        cmdInsert.ExecuteScalar()
                    End Using
                Next

                For Each row As DataGridViewRow In DataGridViewStringsBulk.SelectedRows

                    If StrCommonSet = False Then
                        'StrTemp = CBList.Text
                        StrTemp = bg_GetCBListText()
                        StrCommonSet = True
                    End If

                    Using cmdInsert As New SqlClient.SqlCommand
                        cmdInsert.Connection = cnSql
                        cmdInsert.CommandTimeout = 0
                        cmdInsert.CommandText = "INSERT INTO TblShortDescLink (StrShort, StrCommon) VALUES ('" & row.Cells("Strshort").Value & "','" & StrTemp & "'" & ")"
                        cmdInsert.ExecuteNonQuery()
                    End Using
                Next
                Using cmdCommonInsert As New SqlCommand("usp_UpdateStrCommon", cnSql)
                    cmdCommonInsert.CommandType = CommandType.StoredProcedure
                    cmdCommonInsert.CommandTimeout = 0
                    cmdCommonInsert.ExecuteNonQuery()
                End Using
            End Using

            'MessageBox.Show("Linking finished")
        Else
            'MessageBox.Show("StrShort must be checked in order to link succesfully")
        End If

    End Sub

    'This Event handler() updates the progress.
    Private Sub backgroundWorker1_ProgressChanged(ByVal sender As System.Object,
    ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

        'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
        Me.ProgressBar2.Enabled = True
        Me.ProgressBar2.Visible = True

    End Sub
    Private Sub backgroundWorker2_ProgressChanged(ByVal sender As System.Object,
    ByVal e2 As ProgressChangedEventArgs) Handles BackgroundWorker2.ProgressChanged

        'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
        Me.ProgressBar3.Enabled = True
        Me.ProgressBar3.Visible = True

    End Sub
    Private Sub backgroundWorker3_ProgressChanged(ByVal sender As System.Object,
    ByVal e3 As ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged

        'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
        Me.ProgressBar4.Enabled = True
        Me.ProgressBar4.Visible = True

    End Sub

    ' This event handler deals with the results of the background operation.
    Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As System.Object,
    ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

        If e.Cancelled = True Then
            ResultLabel.Text = "Canceled!"
        ElseIf e.Error IsNot Nothing Then
            ResultLabel.Text = "Error: " & e.Error.Message
        Else

            Me.ProgressBar2.Enabled = False
            Me.ProgressBar2.Visible = False
            Me.Panel1.Enabled = True
            Me.PanelBtnBulkTag.Enabled = True
            ResultLabel.Visible = False
        End If
    End Sub

    Private Sub backgroundWorker2_RunWorkerCompleted(ByVal sender As System.Object,
    ByVal e2 As RunWorkerCompletedEventArgs) Handles BackgroundWorker2.RunWorkerCompleted


        If e2.Cancelled = True Then
            ResultLabelTag.Text = "Canceled!"

        ElseIf e2.Error IsNot Nothing Then
            ResultLabelTag.Text = "Error: " & e2.Error.Message
        Else
            ListBulk.DataSource = GetDataBulk().AsEnumerable().Select(Function(r) r.Field(Of String)("Word")).ToList()
            LblBulkCount.Text = "Words to Tag: " & ListBulk.Items.Count

            Me.ProgressBar3.Enabled = False
            Me.ProgressBar3.Visible = False
            Me.PanelBtnBulkTag.Enabled = True
            Me.Panel1.Enabled = True
            ResultLabelTag.Visible = False
            ListBulk.Refresh()
        End If
    End Sub
    Private Sub backgroundWorker3_RunWorkerCompleted(ByVal sender As System.Object,
    ByVal e3 As RunWorkerCompletedEventArgs) Handles BackgroundWorker3.RunWorkerCompleted


        If e3.Cancelled = True Then
            ResultLabelLink.Text = "Canceled!"

        ElseIf e3.Error IsNot Nothing Then
            ResultLabelLink.Text = "Error: " & e3.Error.Message
        Else

            DataGroupCallStringsBulk()

            Me.ProgressBar4.Enabled = False
            Me.ProgressBar4.Visible = False
            Me.CBList.Enabled = True

            ResultLabelLink.Visible = False
            DataGridViewStringsBulk.Refresh()

        End If
    End Sub

Open in new window

0
 
LVL 13

Expert Comment

by:ktaczala
ID: 42092281
What was the error message?
I built a dummy app and it ran just fine.
0
 
LVL 13

Assisted Solution

by:ktaczala
ktaczala earned 1000 total points
ID: 42092286
try removing the line: "Return CBList.text"  just above the "Else" command.
0
 
LVL 13

Expert Comment

by:ktaczala
ID: 42092288
Here's a MS page with info on how to use delegates:

https://code.msdn.microsoft.com/windowsdesktop/BackGroundWorker-25598fff
0
 
LVL 13

Expert Comment

by:ktaczala
ID: 42092290
Also try changing it to a Sub instead of Function and use a public or private  Variable that both can access.
0
 
LVL 34

Accepted Solution

by:
it_saige earned 1000 total points
ID: 42092362
Okay so some changes since I was able to test this:
Private Sub startAsyncButton3_Click(ByVal sender As Object, ByVal e3 As EventArgs) Handles CBList.SelectedIndexChanged
    If BackgroundWorker3.IsBusy <> True Then
        ' Start the asynchronous operation.

        Me.ResultLabelLink.Visible = True
        Me.ResultLabelLink.Text = "Processing Link Words"
        Me.ProgressBar4.Visible = True
        Me.ProgressBar4.Enabled = True
        'Me.CBList.Enabled = False

        'Me.StrShortCancel.Enabled = True

        BackgroundWorker3.RunWorkerAsync(New With {.Term = CBList.Text, .Viewed = OPBulkDescView4.Checked, .RowCount = DataGridViewStringsBulk.RowCount, .SelectedRows = DataGridViewStringsBulk.SelectedRows.Cast(Of DataGridViewRow)})
    End If
End Sub


Private Sub backgroundWorker3_DoWork(ByVal sender As Object, ByVal e3 As DoWorkEventArgs) Handles BackgroundWorker3.DoWork
    Dim worker = DirectCast(sender, BackgroundWorker)
    Dim deletions As New List(Of String)
    Dim StrCommonSet As Boolean
    Dim StrTemp As String = ""
    Dim Viewed As Boolean = False
    Dim RowCount As Integer = 0
    Dim SelectedRows As New List(Of DataGridViewRow)()
    Dim y As Integer
    If e3.Argument IsNot Nothing Then
        StrTemp = e3.Argument.Term
        Viewed = e3.Argument.Viewed
        RowCount = e3.Argument.RowCount
        SelectedRows = DirectCast(e3.Argument.SelectedRows, IEnumerable(Of DataGridViewRow)).ToList()
    End If
    'adds common word selected to link table
    StrCommonSet = False

    If Viewed Then
        Using cnSql As New SqlClient.SqlConnection("Data Source=MAIN-PC\SQLEXPRESS;Initial Catalog=Dictionary;Integrated Security=True;MultipleActiveResultSets=True")
            cnSql.Open()
            y = RowCount
            For Each row In SelectedRows
                If Not Convert.IsDBNull(row.Cells("StrCommon").Value) Then
                    If Not deletions.Contains(row.Cells("StrCommon").Value, StringComparer.OrdinalIgnoreCase) Then
                        deletions.Add(row.Cells("StrCommon").Value)
                    End If

                End If
            Next

            For Each term In deletions
                Using cmdInsert As New SqlCommand("usp_DeleteShortDescLinkWords", cnSql)
                    cmdInsert.CommandType = CommandType.StoredProcedure
                    cmdInsert.CommandTimeout = 0
                    cmdInsert.Parameters.AddWithValue("@Word", term)
                    cmdInsert.ExecuteScalar()
                End Using
            Next

            For Each row In SelectedRows
                If StrCommonSet = False Then
                    StrCommonSet = True
                End If

                Using cmdInsert As New SqlClient.SqlCommand
                    cmdInsert.Connection = cnSql
                    cmdInsert.CommandTimeout = 0
                    cmdInsert.CommandText = "INSERT INTO TblShortDescLink (StrShort, StrCommon) VALUES ('" & row.Cells("Strshort").Value & "','" & StrTemp & "'" & ")"
                    cmdInsert.ExecuteNonQuery()
                End Using
            Next
            Using cmdCommonInsert As New SqlCommand("usp_UpdateStrCommon", cnSql)
                cmdCommonInsert.CommandType = CommandType.StoredProcedure
                cmdCommonInsert.CommandTimeout = 0
                cmdCommonInsert.ExecuteNonQuery()
            End Using
        End Using

        'MessageBox.Show("Linking finished")
    Else
        'MessageBox.Show("StrShort must be checked in order to link succesfully")
    End If
End Sub

Private Sub backgroundWorker3_ProgressChanged(ByVal sender As Object, ByVal e3 As ProgressChangedEventArgs) Handles BackgroundWorker3.ProgressChanged

    'ResultLabel.Text = "Started Processing" + (e.ProgressPercentage.ToString() + "%")
    Me.ProgressBar4.Enabled = True
    Me.ProgressBar4.Visible = True

End Sub


Private Sub backgroundWorker3_RunWorkerCompleted(ByVal sender As Object, ByVal e3 As RunWorkerCompletedEventArgs) Handles BackgroundWorker3.RunWorkerCompleted


    If e3.Cancelled = True Then
        ResultLabelLink.Text = "Canceled!"

    ElseIf e3.Error IsNot Nothing Then
        ResultLabelLink.Text = "Error: " & e3.Error.Message
    Else

        DataGroupCallStringsBulk()

        Me.ProgressBar4.Enabled = False
        Me.ProgressBar4.Visible = False
        Me.CBList.Enabled = True

        ResultLabelLink.Visible = False
        DataGridViewStringsBulk.Refresh()

    End If
End Sub

Open in new window


Proof of concept -

Form1.vb -
Imports System.Runtime.CompilerServices
Imports System.ComponentModel

Public Class Form1
    Private Sub OnLoad(sender As Object, e As EventArgs) Handles MyBase.Load
        DataGridView1.DataSource = (From i In Enumerable.Range(0, 20) Select New With {.ID = i, .FirstName = String.Format("{0}{1}", If(i Mod 5 = 0, "Paul", If(i Mod 4 = 0, "Larry", If(i Mod 3 = 0, "Susan", If(i Mod 2 = 0, "Mary", "Peter")))), i), .LastName = String.Format("LastName{0}", i), .BirthDate = DateTime.Now.AddYears(-(9 * i)), .IsWorking = i Mod 2 = 0}).ConvertToDataTable()
        Dim columns As New List(Of String)(From column As DataColumn In CType(DataGridView1.DataSource, DataTable).Columns Select column.ColumnName)
        columns.Insert(0, "- All Columns -")
        ComboBox1.DataSource = columns
    End Sub

    Private Sub OnKeyUp(sender As Object, e As KeyEventArgs) Handles TextBox1.KeyUp
        Dim tb = DirectCast(sender, TextBox)
        If tb.Equals(TextBox1) Then
            If e.KeyCode.Equals(Keys.Enter) Then
                DataGridView1.SearchAndSelect(tb.Text, ComboBox1.SelectedItem, True)
                If Not BackgroundWorker1.IsBusy Then
                    BackgroundWorker1.RunWorkerAsync(New With {tb.Text, .Viewed = True, .Count = DataGridView1.RowCount, .SelectedRows = DataGridView1.SelectedRows.Cast(Of DataGridViewRow)})
                End If
                tb.Clear()
                e.Handled = True
            End If
        End If
    End Sub

    Private Sub OnClick(sender As Object, e As EventArgs) Handles Button1.Click
        MessageBox.Show(String.Format("Selected Rows = {1}{0}Values:{2}", Environment.NewLine, DataGridView1.SelectedRows.Count, String.Join(Environment.NewLine, (From selected As DataGridViewRow In DataGridView1.SelectedRows Let row = CType(selected.DataBoundItem, DataRowView).Row Select New With {.ID = row("ID"), .FirstName = row("FirstName"), .LastName = row("LastName"), .BirthDate = row("BirthDate"), .IsWorking = row("IsWorking")}))))
    End Sub

    Private Sub OnDoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        Dim term = String.Empty
        Dim viewed = False
        Dim count = 0
        Dim selectedRows = New List(Of DataGridViewRow)
        If e.Argument IsNot Nothing Then
            term = e.Argument.Text
            viewed = e.Argument.Viewed
            count = e.Argument.Count
            selectedRows = DirectCast(e.Argument.SelectedRows, IEnumerable(Of DataGridViewRow)).ToList()
        End If

        If viewed Then
            MessageBox.Show(String.Format("Term: {1}{0}Selected Rows = {2}{0}Values:{3}", Environment.NewLine, term, count, String.Join(Environment.NewLine, (From selected In selectedRows Let row = CType(selected.DataBoundItem, DataRowView).Row Select New With {.ID = row("ID"), .FirstName = row("FirstName"), .LastName = row("LastName"), .BirthDate = row("BirthDate"), .IsWorking = row("IsWorking")}))))
        End If
    End Sub

    Private Sub OnProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged

    End Sub

    Private Sub OnRunWorkerCompleted(sender As Object, e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted

    End Sub
End Class

Module Extensions
    <Extension()>
    Public Function ConvertToDataTable(Of T)(ByVal source As IEnumerable(Of T)) As DataTable
        Dim properties As PropertyDescriptorCollection = TypeDescriptor.GetProperties(GetType(T))
        Dim table As DataTable = New DataTable()

        For i As Integer = 0 To properties.Count - 1
            Dim [property] As PropertyDescriptor = properties(i)
            If [property].PropertyType.IsGenericType AndAlso [property].PropertyType.GetGenericTypeDefinition().Equals(GetType(Nullable)) Then
                table.Columns.Add([property].Name, [property].PropertyType.GetGenericArguments()(0))
            Else
                table.Columns.Add([property].Name, [property].PropertyType)
            End If
        Next

        Dim values(properties.Count - 1) As Object
        For Each item As T In source
            For i As Integer = 0 To properties.Count - 1
                values(i) = properties(i).GetValue(item)
            Next
            table.Rows.Add(values)
        Next

        Return table
    End Function

    <Extension()>
    Public Sub SearchAndSelect(grid As DataGridView, term As String, selector As String, Optional clearSelected As Boolean = False)
        If grid IsNot Nothing AndAlso grid.Rows.Count < 1 Then Return
        If String.IsNullOrWhiteSpace(term) Then Return
        grid.BeginEdit(True)
        Dim counter = 0
        If clearSelected Then
            For Each row In grid.SelectedRows.Cast(Of DataGridViewRow)()
                row.Selected = False
            Next
        End If

        For Each row In grid.Rows.Cast(Of DataGridViewRow)()
            If selector <> "- All Columns -" Then
                If row.Cells(selector).Value IsNot Nothing AndAlso row.Cells(selector).Value.ToString().IndexOf(term, StringComparison.OrdinalIgnoreCase) <> -1 Then
                    row.Selected = True
                    counter += 1
                    Continue For
                End If
            Else
                For Each column In grid.Columns.Cast(Of DataGridViewColumn)()
                    If row.Cells(column.Name).Value IsNot Nothing AndAlso row.Cells(column.Name).Value.ToString().IndexOf(term, StringComparison.OrdinalIgnoreCase) <> -1 Then
                        row.Selected = True
                        counter += 1
                        Exit For
                    End If
                Next
            End If
        Next
        grid.EndEdit()

        If counter = 0 Then MessageBox.Show(String.Format("No rows were found that matched - {0}", term))
        If grid.SelectedRows.Count > 0 Then
            grid.FirstDisplayedScrollingRowIndex = grid.SelectedRows.Cast(Of DataGridViewRow).Reverse()(0).Index
        End If
    End Sub
End Module

Open in new window

Form1.Designer.vb -
<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()>
Partial Class Form1
    Inherits System.Windows.Forms.Form

    'Form overrides dispose to clean up the component list.
    <System.Diagnostics.DebuggerNonUserCode()>
    Protected Overrides Sub Dispose(ByVal disposing As Boolean)
        Try
            If disposing AndAlso components IsNot Nothing Then
                components.Dispose()
            End If
        Finally
            MyBase.Dispose(disposing)
        End Try
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()>
    Private Sub InitializeComponent()
        Me.Label1 = New System.Windows.Forms.Label()
        Me.TextBox1 = New System.Windows.Forms.TextBox()
        Me.Label2 = New System.Windows.Forms.Label()
        Me.ComboBox1 = New System.Windows.Forms.ComboBox()
        Me.DataGridView1 = New System.Windows.Forms.DataGridView()
        Me.Button1 = New System.Windows.Forms.Button()
        Me.BackgroundWorker1 = New System.ComponentModel.BackgroundWorker()
        CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).BeginInit()
        Me.SuspendLayout()
        '
        'Label1
        '
        Me.Label1.AutoSize = True
        Me.Label1.Location = New System.Drawing.Point(12, 16)
        Me.Label1.Name = "Label1"
        Me.Label1.Size = New System.Drawing.Size(62, 13)
        Me.Label1.TabIndex = 0
        Me.Label1.Text = "Search For:"
        '
        'TextBox1
        '
        Me.TextBox1.Location = New System.Drawing.Point(80, 12)
        Me.TextBox1.Name = "TextBox1"
        Me.TextBox1.Size = New System.Drawing.Size(253, 20)
        Me.TextBox1.TabIndex = 1
        '
        'Label2
        '
        Me.Label2.AutoSize = True
        Me.Label2.Location = New System.Drawing.Point(348, 16)
        Me.Label2.Name = "Label2"
        Me.Label2.Size = New System.Drawing.Size(33, 13)
        Me.Label2.TabIndex = 2
        Me.Label2.Text = "From:"
        '
        'ComboBox1
        '
        Me.ComboBox1.FormattingEnabled = True
        Me.ComboBox1.Location = New System.Drawing.Point(387, 12)
        Me.ComboBox1.Name = "ComboBox1"
        Me.ComboBox1.Size = New System.Drawing.Size(196, 21)
        Me.ComboBox1.TabIndex = 3
        '
        'DataGridView1
        '
        Me.DataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize
        Me.DataGridView1.Location = New System.Drawing.Point(15, 39)
        Me.DataGridView1.Name = "DataGridView1"
        Me.DataGridView1.RowHeadersVisible = False
        Me.DataGridView1.SelectionMode = System.Windows.Forms.DataGridViewSelectionMode.FullRowSelect
        Me.DataGridView1.Size = New System.Drawing.Size(568, 216)
        Me.DataGridView1.TabIndex = 4
        '
        'Button1
        '
        Me.Button1.Location = New System.Drawing.Point(430, 262)
        Me.Button1.Name = "Button1"
        Me.Button1.Size = New System.Drawing.Size(152, 23)
        Me.Button1.TabIndex = 5
        Me.Button1.Text = "Get Selected Records"
        Me.Button1.UseVisualStyleBackColor = True
        '
        'Form1
        '
        Me.AutoScaleDimensions = New System.Drawing.SizeF(6.0!, 13.0!)
        Me.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font
        Me.ClientSize = New System.Drawing.Size(595, 289)
        Me.Controls.Add(Me.Button1)
        Me.Controls.Add(Me.DataGridView1)
        Me.Controls.Add(Me.ComboBox1)
        Me.Controls.Add(Me.Label2)
        Me.Controls.Add(Me.TextBox1)
        Me.Controls.Add(Me.Label1)
        Me.Name = "Form1"
        Me.Text = "Form1"
        CType(Me.DataGridView1, System.ComponentModel.ISupportInitialize).EndInit()
        Me.ResumeLayout(False)
        Me.PerformLayout()

    End Sub
    Friend WithEvents Label1 As System.Windows.Forms.Label
    Friend WithEvents TextBox1 As System.Windows.Forms.TextBox
    Friend WithEvents Label2 As System.Windows.Forms.Label
    Friend WithEvents ComboBox1 As System.Windows.Forms.ComboBox
    Friend WithEvents DataGridView1 As System.Windows.Forms.DataGridView
    Friend WithEvents Button1 As System.Windows.Forms.Button
    Friend WithEvents BackgroundWorker1 As System.ComponentModel.BackgroundWorker
End Class

Open in new window


Produces the following output -
Initial load -Capture.PNGSearching for mary -Capture.PNGSearching for peter -Capture.PNG
-saige-
0
 

Author Closing Comment

by:PeterBaileyUk
ID: 42092833
thank you both for taking time to not only show a solution but to guide me to the use of delagates and also to IT saige for the proof of concepts I find those so so useful to understand the underlying technique.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction As chip makers focus on adding processor cores over increasing clock speed, developers need to utilize the features of modern CPUs.  One of the ways we can do this is by implementing parallel algorithms in our software.   One recent…
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
In this video, Percona Solution Engineer Dimitri Vanoverbeke discusses why you want to use at least three nodes in a database cluster. To discuss how Percona Consulting can help with your design and architecture needs for your database and infras…
How to fix incompatible JVM issue while installing Eclipse While installing Eclipse in windows, got one error like above and unable to proceed with the installation. This video describes how to successfully install Eclipse. How to solve incompa…
Suggested Courses

719 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question