Hi,

I have the below code in an MDI childform which saves a dataset to a temp
file.

Trouble is, while this process is running (can sometimes be up to several
minutes), the interface is effectively blocked ... so I want to try and run
this process in another asynchronous thread in the background, and when it's
finished it would raise an event on the MDI app and the form that started it
to tell the user the file is written. While the process is running, the
interface would still be available, and the user could access the MDI menus
to do something else (run an alternative query on another form)

Here is the code I have:

(BTW, m_MainForm is the MDI container)
>>>> CODE >>>>
Private Sub saveTempFile(Optional ByVal sTempPath As String = "c:\temp\")

Dim ds As DataSet = dgMain.DataSource
Dim xmlDOMSchema As New XmlDocument
Dim strCSV As String
Dim xNode As XmlNode
Dim strFileName As String = sTempPath & "ldsdata_" & Format(Now(),
"yyyymmdd hhmmss") & "_" & Me.cboConnections.Text & ".csv"
Dim iRowCount As Int64

Dim iMax As Int16
Dim dblPctDone As Double

Dim oCSVFile As StreamWriter = New StreamWriter(strFileName)

Dim ProgressForm As New frmProgress

Try
With ProgressForm
.MdiParent = Me.MdiParent
.Left = Me.Left
.Top = Me.Top + Me.Height
.Width = Me.Width
.lblProgress.Width = Me.Width - 32
iMax = Me.Width - 32
.Show()
End With

Cursor = Cursors.WaitCursor

' update the forms status lable with the current state
setStatus("Writing to '" & strFileName & "' ...")

' update the MDI Form status bar
m_MainForm.sbAppMsg.Text = "Writing to '" & strFileName & "' ... please be
patient"

xmlDOMSchema.LoadXml(ds.GetXmlSchema)

' the xPath just navigates through the node-levels until we
' get to the interesting data (column heads) ....
For Each xNode In
xmlDOMSchema.SelectNodes("//*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*")
strCSV += xNode.Attributes("name").Value & ","
Next
strCSV = Microsoft.VisualBasic.Left(strCSV, Len(strCSV) - 1)
strCSV += vbCrLf

For Each oRecord As System.Data.DataRow In
ds.Tables("resultset01").Rows

' navigate through the levels of the DOM to the recordset
For Each xNode In
xmlDOMSchema.SelectNodes("//*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*")

If xNode.Attributes("type").Value = "xs:string" Then
strCSV += Chr(34) &
oRecord.Item(xNode.Attributes("name").Value) & Chr(34) & ","
Else
If
IsDBNull(oRecord.Item(xNode.Attributes("name").Value)) Then
strCSV += ","
Else
strCSV +=
oRecord.Item(xNode.Attributes("name").Value) & ","
End If

End If
Next
strCSV = Microsoft.VisualBasic.Left(strCSV, Len(strCSV) - 1)
iRowCount += 1

If ds.Tables("resultset01").Rows.Count > 1999 Then
If iRowCount Mod 1000 = 0 Then
Application.DoEvents()
setStatus(iRowCount & " records written to csv
file...")
Me.Refresh()
End If
End If

' update the progress indicator - flood panel...
dblPctDone = iRowCount / ds.Tables("resultset01").Rows.Count

With ProgressForm
.imgProgress.Width = dblPctDone * iMax
.Refresh()
End With

oCSVFile.WriteLine(strCSV)
strCSV = ""

Application.DoEvents()

Next

oCSVFile.Close()
ProgressForm.Dispose()

m_MainForm.sbAppMsg.Text = "Ready"

Catch ex As Exception
MessageBox.Show("An error occurred while saving the data to a
temporary file." & vbCrLf & vbCrLf & ex.Message, _
"saveTempFile", MessageBoxButtons.OK,
MessageBoxIcon.Error)
setStatus(ex.Message)

End Try

Cursor = Cursors.Default

End Sub
' <<<< END CODE <<<<

can anyone help me with this?

thanks

Philip

Re: Help needed with Asynchronous threading by Stoitcho

Stoitcho
Thu Jan 18 13:53:41 CST 2007

Philip,

I'd suggest to take a look at the BackgroundWorker conponent. Using this
component you can exectute lengthy procedure on a bacground thread, so the
UI doesn't get blocked. In addition the component fires event when the work
is done as well as events for updating progress information, which events
are synchronized with the main UI thread so you can update the controls
directly.


--
HTH
Stoitcho Goutsev (100)

"Philip" <Philip@discussions.microsoft.com> wrote in message
news:71FE98C7-A73A-41C5-9A8E-04C0A471138C@microsoft.com...
> Hi,
>
> I have the below code in an MDI childform which saves a dataset to a temp
> file.
>
> Trouble is, while this process is running (can sometimes be up to several
> minutes), the interface is effectively blocked ... so I want to try and
> run
> this process in another asynchronous thread in the background, and when
> it's
> finished it would raise an event on the MDI app and the form that started
> it
> to tell the user the file is written. While the process is running, the
> interface would still be available, and the user could access the MDI
> menus
> to do something else (run an alternative query on another form)
>
> Here is the code I have:
>
> (BTW, m_MainForm is the MDI container)
>>>>> CODE >>>>
> Private Sub saveTempFile(Optional ByVal sTempPath As String =
> "c:\temp\")
>
> Dim ds As DataSet = dgMain.DataSource
> Dim xmlDOMSchema As New XmlDocument
> Dim strCSV As String
> Dim xNode As XmlNode
> Dim strFileName As String = sTempPath & "ldsdata_" & Format(Now(),
> "yyyymmdd hhmmss") & "_" & Me.cboConnections.Text & ".csv"
> Dim iRowCount As Int64
>
> Dim iMax As Int16
> Dim dblPctDone As Double
>
> Dim oCSVFile As StreamWriter = New StreamWriter(strFileName)
>
> Dim ProgressForm As New frmProgress
>
> Try
> With ProgressForm
> .MdiParent = Me.MdiParent
> .Left = Me.Left
> .Top = Me.Top + Me.Height
> .Width = Me.Width
> .lblProgress.Width = Me.Width - 32
> iMax = Me.Width - 32
> .Show()
> End With
>
> Cursor = Cursors.WaitCursor
>
> ' update the forms status lable with the current state
> setStatus("Writing to '" & strFileName & "' ...")
>
> ' update the MDI Form status bar
> m_MainForm.sbAppMsg.Text = "Writing to '" & strFileName & "' ... please be
> patient"
>
> xmlDOMSchema.LoadXml(ds.GetXmlSchema)
>
> ' the xPath just navigates through the node-levels until we
> ' get to the interesting data (column heads) ....
> For Each xNode In
> xmlDOMSchema.SelectNodes("//*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*")
> strCSV += xNode.Attributes("name").Value & ","
> Next
> strCSV = Microsoft.VisualBasic.Left(strCSV, Len(strCSV) - 1)
> strCSV += vbCrLf
>
> For Each oRecord As System.Data.DataRow In
> ds.Tables("resultset01").Rows
>
> ' navigate through the levels of the DOM to the recordset
> For Each xNode In
> xmlDOMSchema.SelectNodes("//*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*[1]/*")
>
> If xNode.Attributes("type").Value = "xs:string" Then
> strCSV += Chr(34) &
> oRecord.Item(xNode.Attributes("name").Value) & Chr(34) & ","
> Else
> If
> IsDBNull(oRecord.Item(xNode.Attributes("name").Value)) Then
> strCSV += ","
> Else
> strCSV +=
> oRecord.Item(xNode.Attributes("name").Value) & ","
> End If
>
> End If
> Next
> strCSV = Microsoft.VisualBasic.Left(strCSV, Len(strCSV) -
> 1)
> iRowCount += 1
>
> If ds.Tables("resultset01").Rows.Count > 1999 Then
> If iRowCount Mod 1000 = 0 Then
> Application.DoEvents()
> setStatus(iRowCount & " records written to csv
> file...")
> Me.Refresh()
> End If
> End If
>
> ' update the progress indicator - flood panel...
> dblPctDone = iRowCount /
> ds.Tables("resultset01").Rows.Count
>
> With ProgressForm
> .imgProgress.Width = dblPctDone * iMax
> .Refresh()
> End With
>
> oCSVFile.WriteLine(strCSV)
> strCSV = ""
>
> Application.DoEvents()
>
> Next
>
> oCSVFile.Close()
> ProgressForm.Dispose()
>
> m_MainForm.sbAppMsg.Text = "Ready"
>
> Catch ex As Exception
> MessageBox.Show("An error occurred while saving the data to a
> temporary file." & vbCrLf & vbCrLf & ex.Message, _
> "saveTempFile", MessageBoxButtons.OK,
> MessageBoxIcon.Error)
> setStatus(ex.Message)
>
> End Try
>
> Cursor = Cursors.Default
>
> End Sub
> ' <<<< END CODE <<<<
>
> can anyone help me with this?
>
> thanks
>
> Philip