Results 1 to 23 of 23

Thread: SqlBulkCopy RowsCopied event not updating TextBox

  1. #1

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    SqlBulkCopy RowsCopied event not updating TextBox

    I don't understand delegates, but I got some help a while back and was able to make it work. Now I have a new project and I did something to break it.
    I have a Background Worker that has an object that's doing SqlBulkCopy. I have this line.
    vb.net Code:
    1. AddHandler bcMain.SqlRowsCopied, New SqlRowsCopiedEventHandler(AddressOf frmMain.OnSqlRowsCopied)
    In my main form I have a sub for updating a TextBox.
    vb.net Code:
    1. Private Delegate Sub AppendResultsDelegate(strMessage As String)
    2. Private Sub AppendResults(strLine As String)
    3.     txtResults.AppendText(strLine & vbCrLf)
    4. End Sub
    This works for everything except the SqlBulkCopy reporting rows copied. The odd thing is when I run the debugger and break on the AppendText line, I can see it doing it, but it's not apparent on the main form. I've tried adding a Refresh() on the control and the form, but it doesn't work. What am I doing wrong?

  2. #2
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    This is probably an issue with default form instances. That first line of code appears to be referring to a default instance. If that code is executed on a secondary thread than that will not be the instance that you think it is, so the code is working but it's updating a TextBox in a different form. Can you show us all of the relevant code?
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  3. #3
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Looks like a cross thread problem to me. You probably need to Invoke txtResults on your BGW thread...

    EDIT: Actually, it's probably what jm said

  4. #4

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Sounds like what might be happening.
    I don't know what would be relevant. I have a default main form frmMain with the text box. frmMain also has the sub I showed above to modify the text box. frmMain also has a sub for the background worker DoWork. In that sub I create an object objDbTools. Just a class of functions I need to changing the Db. It has a function BulkUploadSuccess. Here it is.
    vb.net Code:
    1. Public Function BulkUploadSuccess(bwMain As System.ComponentModel.BackgroundWorker,
    2.                                   dtTemp As DataTable) As Boolean
    3.     strException = ""
    4.     Using bcMain = New SqlBulkCopy(objConn.ConnectionString)
    5.         AddHandler bcMain.SqlRowsCopied, New SqlRowsCopiedEventHandler(AddressOf frmMain.OnSqlRowsCopied)
    6.         bcMain.NotifyAfter = My.Settings.BatchSize
    7.         bcMain.BatchSize = My.Settings.BatchSize
    8.         bcMain.DestinationTableName = My.Settings.DestinationTable
    9.         bcMain.BulkCopyTimeout = My.Settings.SQLCommandTimeout
    10.         For Each column As DataColumn In dtTemp.Columns
    11.             bcMain.ColumnMappings.Add(column.ColumnName, column.ColumnName)
    12.         Next
    13.         Try
    14.             bcMain.WriteToServer(dtTemp)
    15.         Catch ex As Exception
    16.             strException = ex.Message
    17.         End Try
    18.     End Using
    19.     If strException = "" Then
    20.         Return True
    21.     Else
    22.         Return False
    23.     End If
    24. End Function
    Is there something else I could show you?
    Thanks for all your help.

  5. #5

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Thanks Paul. Sounds about right, but I don't know how to do that.
    I really need to learn about these someday...

  6. #6

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Thanks Paul, "Invoke" got me to looking and I see what I failed to copy over from the working project. I was playing with some things and forgot to put somehting back.
    vb.net Code:
    1. Me.Invoke(New AppendResultsDelegate(AddressOf AppendResults), strMessage)
    Thank you both! You guys are benevolent gods.

  7. #7
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    The DoWork event handler of the BackgroundWorker is executed on a secondary thread. If that BulkUploadSuccess method is called from that event handler then it is also executed on that secondary thread. That means that this line:
    Code:
    AddHandler bcMain.SqlRowsCopied, New SqlRowsCopiedEventHandler(AddressOf frmMain.OnSqlRowsCopied)
    is referring to the default instance of frmMain that is specific to that thread, which is NOT the instance that you are looking at. Like I said, the code is working but it is updating a TextBox on a form that you are not looking at and have never actually shown. You need to refer to the actual instance of frmMain that you have displayed, NOT the default instance.

    Probably your best bet would be for that BulkUploadSuccess to have an extra parameter by which to pass the event handler delegate:
    vb.net Code:
    1. Public Function BulkUploadSuccess(bwMain As System.ComponentModel.BackgroundWorker,
    2.                                   dtTemp As DataTable,
    3.                                   onSqlRowsCopied As SqlRowsCopiedEventHandler) As Boolean
    4.     strException = ""
    5.     Using bcMain = New SqlBulkCopy(objConn.ConnectionString)
    6.         AddHandler bcMain.SqlRowsCopied, onSqlRowsCopied
    You can then create the delegate in the form itself, so you know that you'll be referring to the correct instance, and pass it into the method.

    By the way, why is that method named BulkUploadSuccess? That sounds more like the name of a variable that indicates whether the operation was successful or not. A method name should be more like BulkUpload or DoBulkUpload.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  8. #8

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    That was all educational and about what I understood, more I don't understand the commands to implement it.

    Many of my routines are fail or success values returned. I use this as my error handing back on where it was called from. So like here it's a condition to report success to the main form or exit the subroutine and report the failure and exceptions to the user and bail on the routine. Just my goofy error handing logic.

  9. #9
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Quote Originally Posted by cory_jackson View Post
    Many of my routines are fail or success values returned. I use this as my error handing back on where it was called from. So like here it's a condition to report success to the main form or exit the subroutine and report the failure and exceptions to the user and bail on the routine. Just my goofy error handing logic.
    There's nothing wrong with a method returning a Boolean to indicate success or failure. The issue is the name. That is not an appropriate method name. Methods are actions and the name should describe the action. Your name indicates that all the method does is determine whether a bulk upload is successful, not that it actually performs the bulk upload.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  10. #10

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Good point. I'll think about that.
    However the fact that it failed or succeeded means it was attempted. And "bulk upload" is the action.
    Also to me it's part of a sentence. "If (the) bulk upload (is a) success, then... else...". So the method's name is clipped form that. It just keeps the logic in my head straight and I know the method is a function that returns a Boolean value without checking.
    But its' a good point. Thank you.

  11. #11
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    I’m not disputing anything JM has told you, but this is the correct way to invoke your TextBox on your secondary thread…


    Code:
    Private Delegate Sub AppendResultsDelegate(strMessage As String)
    Private Sub AppendResults(strLine As String)
        If txtResults.InvokeRequired Then
            txtResults.Invoke(New AppendResultsDelegate(AddressOf AppendResults), strMessage)
        Else
            txtResults.AppendText(strLine & vbCrLf)
        End If
    End Sub

  12. #12
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Quote Originally Posted by .paul. View Post
    I’m not disputing anything JM has told you, but this is the correct way to invoke your TextBox on your secondary thread…


    Code:
    Private Delegate Sub AppendResultsDelegate(strMessage As String)
    Private Sub AppendResults(strLine As String)
        If txtResults.InvokeRequired Then
            txtResults.Invoke(New AppendResultsDelegate(AddressOf AppendResults), strMessage)
        Else
            txtResults.AppendText(strLine & vbCrLf)
        End If
    End Sub
    I would also suggest that there's no point declaring your own delegate these days. In this case, an Action(Of String) delegate would be appropriate. The Framework includes Action and Func delegates for Subs and Functions with zero to 16 parameters.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  13. #13

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Oh cool! Thank you.

  14. #14

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    I'd like to learn how to do this.
    Would you be willing to show my how I would do this in my case?

  15. #15
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    I’d also like to see Action and Func delegates for this case…

  16. #16
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Quote Originally Posted by cory_jackson View Post
    I'd like to learn how to do this.
    Would you be willing to show my how I would do this in my case?
    Are you referring to the use of an Action delegate? When there are multiple posts, please quote what you are replying to so that we know. If that is the case then simply get rid of your own delegate declaration and use an Action(Of String) delegate instead. That's all there is to it.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  17. #17
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    To Invoke without a delegate...

    Code:
    Private Sub AppendResults(ByVal strLine As String)
        If txtResults.InvokeRequired Then
            txtResults.Invoke(New Action(Of String)(AddressOf AppendResults), strLine)
        Else
            txtResults.AppendText(strLine & vbCrLf)
        End If
    End Sub

  18. #18
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    26,413

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Code:
    AddHandler bcMain.SqlRowsCopied, AddressOf bcMain_SqlRowsCopied
    Code:
    Private Sub bcMain_SqlRowsCopied(sender As Object, e As SqlRowsCopiedEventArgs)
        ' your code
    End Sub

  19. #19

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    I'm messing this up somehow. I just don't understand.
    In my dbTools class I have this function.
    vb.net Code:
    1. Public Function BulkUploadSuccess(bwMain As System.ComponentModel.BackgroundWorker,
    2.                                   dtTemp As DataTable) As Boolean
    3.     strException = ""
    4.     Using bcMain = New SqlBulkCopy(objConn.ConnectionString)
    5.         AddHandler bcMain.SqlRowsCopied, New SqlRowsCopiedEventHandler(AddressOf frmMain.SqlRowsCopied)
    6.         bcMain.NotifyAfter = My.Settings.BatchSize
    7.         bcMain.BatchSize = My.Settings.BatchSize
    8.         bcMain.DestinationTableName = My.Settings.DestinationTable
    9.         bcMain.BulkCopyTimeout = My.Settings.SQLCommandTimeout
    10.         For Each column As DataColumn In dtTemp.Columns
    11.             bcMain.ColumnMappings.Add(column.ColumnName, column.ColumnName)
    12.         Next
    13.         Try
    14.             bcMain.WriteToServer(dtTemp)
    15.         Catch ex As Exception
    16.             strException = ex.Message
    17.         End Try
    18.     End Using
    19.     If strException = "" Then
    20.         Return True
    21.     Else
    22.         Return False
    23.     End If
    24. End Function
    Then in the main form I have this sub.
    vb.net Code:
    1. Public Sub OnSqlRowsCopied(ByVal sender As Object, ByVal e As SqlClient.SqlRowsCopiedEventArgs)
    2.     AppendResults(String.Concat("Copied: ", e.RowsCopied))
    3. End Sub
    And finally
    vb.net Code:
    1. Private Sub AppendResults(strLine As String)
    2.     If txtResults.InvokeRequired Then
    3.         txtResults.Invoke(New Action(Of String)(AddressOf AppendResults), strLine)
    4.     Else
    5.         txtResults.AppendText(strLine & vbCrLf)
    6.     End If
    7. End Sub
    What do I have wrong?

  20. #20
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Where is that BulkUploadSuccess called? Is it in the DoWork event handler of the BackgroundWorker? If so then I've already explained what the problem is and what the solution is.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  21. #21

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    OK, my mistake. I just don't understand how this works. Thanks. I tried to mimic what Paul posted and it didn't work.

    It's a method in the dbTools object in DoWork.

  22. #22
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    111,221

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    There are potentially two issues at play here, both related to multithreading. Think it through.

    As I have already stated, default instances are thread-specific. If you are calling that BulkUploadSuccess method on a secondary thread then the default instance of frmMain is specific to that thread and of no use to you. I have already told you what to do about that.

    Also, if you are calling the AppendResults method on a secondary thread then you can't access controls directly there either. If the SqlRowsCopied event handler is raised on a secondary thread then that will be the case and that is why .paul. told you to do as he did.
    Why is my data not saved to my database? | MSDN Data Walkthroughs
    VBForums Database Development FAQ
    My CodeBank Submissions: VB | C#
    My Blog: Data Among Multiple Forms (3 parts)
    Beginner Tutorials: VB | C# | SQL

  23. #23

    Thread Starter
    Frenzied Member cory_jackson's Avatar
    Join Date
    Dec 2011
    Location
    Fallbrook, California
    Posts
    1,145

    Re: SqlBulkCopy RowsCopied event not updating TextBox

    Thank you

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width