0

I have a simple web application that is reading records from a CSV file and storing them in a database table. Then I am using SqlBulkCopy to copy the records into an SQL database using batches. All is fine with the insert. I am trying to give the user some feedback using OnSqlRowsCopied and NotifyAfter. The goal is to update a label that is contained in an UpdatePanel to display the number of records copied at the current NotifyAfter interval. However, the label will not update until SqlBulkCopy has complete. I can see that the s_OnSqlRowsCopied event is firing using Debug.WriteLine. What is the reason why the label won't update and how can I overcome this?

Code Behind

Imports System.Data.SqlClient

Public Class WebForm1
Inherits System.Web.UI.Page

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

End Sub

Dim filePath As String
Dim rowsCopied As String

Public Sub btnGetCSV_Click(sender As Object, e As EventArgs) Handles btnGetCSV.Click



    filePath = System.IO.Path.GetFullPath(fileUpload1.PostedFile.FileName)
    lblInfo.Text = filePath



End Sub

Protected Sub btnToSQL_Click(sender As Object, e As EventArgs) Handles btnToSQL.Click

    Dim cs As String = System.Web.Configuration.WebConfigurationManager.ConnectionStrings("csMediaPortal").ConnectionString
    CopyData(CSVtoDataTable(lblInfo.Text.ToString()), cs)

End Sub

Private Function CSVtoDataTable(filePath As String) As DataTable

    Dim dt As DataTable = Nothing
    Dim sourcePath As String = String.Empty
    Dim csvFile As String = String.Empty
    Dim conString As String = String.Empty
    Dim conn As OleDb.OleDbConnection = Nothing
    Dim adapter As OleDb.OleDbDataAdapter = Nothing
    Dim selString As String = String.Empty

    Try
        sourcePath = System.IO.Path.GetDirectoryName(filePath)
        csvFile = System.IO.Path.GetFileName(filePath)
        conString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & sourcePath & ";Extended Properties=""text;HDR=No;FMT=FixedLength"""
        conn = New OleDb.OleDbConnection(conString)
        selString = "Select * From " & csvFile
        adapter = New OleDb.OleDbDataAdapter(selString, conn)
        dt = New DataTable(System.IO.Path.GetFileNameWithoutExtension(filePath))
        conn.Open()
        adapter.Fill(dt)
        conn.Close()
    Catch ex As Exception
        lblInfo.Text = ex.Message
    Finally
        adapter.Dispose()
        conn.Dispose()
    End Try

    Return dt

End Function

Protected Sub CopyData(sourceTable As DataTable, cs As String)

    Using s As SqlBulkCopy = New SqlBulkCopy(cs, SqlBulkCopyOptions.UseInternalTransaction)

        s.DestinationTableName = "test"
        s.BatchSize = 1000


        Try
            AddHandler s.SqlRowsCopied, AddressOf s_OnSqlRowsCopied

            s.NotifyAfter = 900
            s.WriteToServer(sourceTable)


        Catch ex As Exception

            DirectCast(DirectCast(HttpContext.Current.Handler, Page).FindControl("lblInfo"), Label).Text = "Commit Error: " & ex.Message

        End Try

        s.Close()

    End Using
End Sub


Protected Sub s_OnSqlRowsCopied(sender As Object, e As SqlRowsCopiedEventArgs)

    Me.lblProgress.Value = e.RowsCopied.ToString()
    Me.UpdatePanel1.Update()
    Debug.WriteLine(e.RowsCopied)

End Sub



End Class

Web Form

    <%@ Page Language="vb" CodeBehind="WebForm1.aspx.vb" Inherits="CSVUpload.WebForm1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server">
        </asp:ScriptManager>
        <div>
            <asp:FileUpload ID="fileUpload1" runat="server" />
            <asp:Button ID="btnGetCSV" runat="server" Text="Post" OnClick="btnGetCSV_Click" />
            <asp:Label ID="lblInfo" runat="server" Text="Label"></asp:Label>
        </div>

        &nbsp;<asp:Button ID="btnToSQL" runat="server" Text="Insert To SQL" OnClick="btnToSQL_Click" />
        <div>
            <asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
                <ContentTemplate>
                    <input runat="server" type="text" id="lblProgress" value="0" />

                </ContentTemplate>
            </asp:UpdatePanel>

        </div>
    </form>
</body>
</html>
Alex Shesterov
  • 26,085
  • 12
  • 82
  • 103
gonzo193
  • 11
  • 2
  • 1
    I'd suggest using a BackgroundWorker, it is designed to update the UI during a long running process. – PatFromCanada Apr 18 '13 at 18:00
  • PatFromCanada, thank you. Your comment sent me in the right direction. I was able to get my project working using the example given here: [http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6/sourcecode?fileId=21970&pathId=285164727](http://code.msdn.microsoft.com/CSASPNETBackgroundWorker-dda8d7b6/sourcecode?fileId=21970&pathId=285164727). – gonzo193 Apr 22 '13 at 14:48

0 Answers0