We help IT Professionals succeed at work.

Multiple Threads using Active Reports

I am using dynamic SQL (put into strSelect in my program) to fill an ActiveReports report. This is the code I use to set the datasource for the report (ActiveReports requires using OleDb in this case) :
           'set up connection string and dataset
            Dim connString As String = "Provider=SQLOLEDB.1;" & myConnectionString
            Dim conn As New OleDb.OleDbConnection(connString)
            conn.Open()
            Dim ds As New DataSet
            Dim da As New OleDb.OleDbDataAdapter(strSelect, conn)
            da.Fill(ds, "Detail")
            rpt.DataSource = ds
            rpt.DataMember = "Detail"
The problem is that the fill can take a long time if there’s a lot of data and the user can’t do anything else. I would like to run fill in a separate thread, but I would have to know when it is finished, so I can run the report. The events I see for OleDbDataAdapter don’t seem to include one for fill completed. Do you know of any other way I can prevent the fill process from locking up the machine?  
Comment
Watch Question

High School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009
Commented:
Drop a BackgroundWorker() control on your form and place the DB code into the DoWork() event.  The RunWorkerCompleted() event will fire when it's all done:

    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        BackgroundWorker1.RunWorkerAsync()
    End Sub

    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        'set up connection string and dataset
        Dim connString As String = "Provider=SQLOLEDB.1;" & myConnectionString
        Dim conn As New OleDb.OleDbConnection(connString)
        conn.Open()
        Dim ds As New DataSet
        Dim da As New OleDb.OleDbDataAdapter(strSelect, conn)
        da.Fill(ds, "Detail")
        rpt.DataSource = ds
        rpt.DataMember = "Detail"
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        ' ...it's all done...
    End Sub
Mike TomlinsonHigh School Computer Science, Computer Applications, Digital Design, and Mathematics Teacher
Top Expert 2009

Commented:
You may need to do it this way instead:

    Private Sub BackgroundWorker1_DoWork(ByVal sender As Object, ByVal e As System.ComponentModel.DoWorkEventArgs) Handles BackgroundWorker1.DoWork
        'set up connection string and dataset
        Dim connString As String = "Provider=SQLOLEDB.1;" & myConnectionString
        Dim conn As New OleDb.OleDbConnection(connString)
        conn.Open()
        Dim ds As New DataSet
        Dim da As New OleDb.OleDbDataAdapter(strSelect, conn)
        da.Fill(ds, "Detail")
        e.Result = ds
    End Sub

    Private Sub BackgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As System.ComponentModel.RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
        rpt.DataSource = CType(e.Result, DataSet)
        rpt.DataMember = "Detail"
    End Sub