Hey Tom,
Thanks for the Reply.
Here is what is some code:
This runs on a menu click handler:
Dim objReports As Reports
objReports = New ExcelPayrollCD(strFullFileName,
g_objTables.Connection, intSerial)
AddHandler objReports.ReportFinished, AddressOf
objReports_ReportFinished
Dim objNewThreadStart As New Threading.ThreadStart(AddressOf
objReports.Generate)
Dim objNewThread As New Threading.Thread(objNewThreadStart)
objNewThread.Start()
And there is this sub to handle the above code:
Private Sub objReports_ReportFinished(ByVal sender As Excel.Reports)
Dim Result As Excel.ReportResults
Result = sender.ReportResult
Dim objNewThreadStart As New Threading.ThreadStart(AddressOf
CType(sender, IDisposable).Dispose)
Dim objNewThread As New Threading.Thread(objNewThreadStart)
objNewThread.Start()
Select Case Result
Case Excel.ReportResults.OK
MessageBox.Show("Report created!" & vbNewLine &
sender.FullFileName & " saved.", "Payroll CD", MessageBoxButtons.OK,
MessageBoxIcon.Information, MessageBoxDefaultButton.Button1)
Case Excel.ReportResults.Cancelled
MessageBox.Show("Report cancelled.")
Case Excel.ReportResults.ConnectionTimeOut
MessageBox.Show("Connection Timed Out.")
Case Excel.ReportResults.DataNotRetrived
MessageBox.Show("Data Not Retrived.")
Case Excel.ReportResults.ReportModelNotFound
MessageBox.Show("Report model not found.")
Case Excel.ReportResults.UnknownError
MessageBox.Show("Unkown Error.")
Case Else
End Select
End Sub
I want to catch an error on objReports.Generate, which is run at
objNewThread.Start.
Normally, without MultiThreading, I'd simply do:
Try
objReports.Generate()
Catch
'do whatever
Finally
objReports.Dispose
End Try
but I can't because there is no direct call to objReports.Generate, and
objReports.Dispose only runs when Sub objReports_ReportFinished gets called.
Any ideas?
Thanks again!
Giovanni Bassi
Giovanni,
Looking over the code, assuming I understand what's happening
, I
would suggest you look into using an async delegate to call a method
that generates the report... I think you will save your self a lot of
trouble, and end up with the same results. Basically, what you would do
is create and call a method, called say GenerateReports, using async
delegate. The GenerateReports method would be as simple as:
Private Delegate Sub GenReportsDelegate()
' menu click...
Private Sub...
Dim async As New GenReportsDelegate(AddressOf Me.GenerateReports)
' now call the method async like...
async.BeginInvoke(AddressOf Me.GenerateReportsComplete, Nothing)
End Sub
' Generate your reports in the background...
Private Sub GenerateReports()
Dim objReports As Reports = _
New ExcelPayrollCD(strFullFileName, g_objTables.Connection, intSerial)
AddHandler objReports.ReportFinished, AddressOf objReports_ReportFinished
Try
objReports.Generate()
Catch
' do whatever
Finally
objReports.Dispose()
End Try
End Sub
' do this so you make sure EndInvoke is called
Private Sub GenerateReportsDone(ByVal ar As IAsyncResult)
Dim async As GenReportsDelegate = _
DirectCast(ar.AsyncState, GenReportsDelegate)
async.EndInvoke(ar)
End Sub
What will change, and I think for the better is that you will eliminate
all the explicit threading, since the system will manage the threads.
Not only that, in the end the code is simpler. I don't have the docs on
this machine to give you a reference in them, but you can find a pretty
good overview in the docs on MSDN...
http://msdn.microsoft.com/library/d...cpguide/html/cpconAsynchronousProgramming.asp
HTH