Hey all, I posted a vague question in the Database forum yesterday about a problem I had with Access file locking. I start another thread to do some work exporting to Access, but when the thread completes I need to copy the Access file over our network - and then delete it.
This was a problem because while the worker thread was alive, the Access file was locked (the goddamn .ldb file). To get around this, I used some Async calls (BeginInvoke, EndInvoke) to execute on the main thread, thus causing the worker thread to end and release the Access lock. I could then delete it..
Now, Ive never really done the whole Async thing before with Begin/End, and the msdn docs are unintuitive to say the least. Ive made a small example below so can someone tell me if im doing this the correct way? The code is complete so can be copied into a project and run.
Thanks all!! Much appreciated.
edit: I dont why but sometimes the BeginInvoke() throws an exception - only sometimes tho! This doesnt happen in my real application!!
This was a problem because while the worker thread was alive, the Access file was locked (the goddamn .ldb file). To get around this, I used some Async calls (BeginInvoke, EndInvoke) to execute on the main thread, thus causing the worker thread to end and release the Access lock. I could then delete it..
Now, Ive never really done the whole Async thing before with Begin/End, and the msdn docs are unintuitive to say the least. Ive made a small example below so can someone tell me if im doing this the correct way? The code is complete so can be copied into a project and run.
Thanks all!! Much appreciated.
edit: I dont why but sometimes the BeginInvoke() throws an exception - only sometimes tho! This doesnt happen in my real application!!
VB.NET:
[COLOR=blue][FONT="]Public[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR] Form[/FONT]
[FONT="] <System.STAThread()> _[/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Shared[/COLOR] [COLOR=blue]Sub[/COLOR] Main()[/FONT]
[FONT="] Application.Run([COLOR=blue]New[/COLOR] Form())[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]WithEvents[/COLOR] lblStatus [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] Label()[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]WithEvents[/COLOR] butDoStuff [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] Button()[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]WithEvents[/COLOR] AsyncMan [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] AsyncManager([COLOR=blue]Me[/COLOR])[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]Sub[/COLOR] Form_Load([COLOR=blue]ByVal[/COLOR] sender [COLOR=blue]As[/COLOR] System.Object, [COLOR=blue]ByVal[/COLOR] e [COLOR=blue]As[/COLOR] System.EventArgs) [COLOR=blue]Handles[/COLOR] [COLOR=blue]MyBase[/COLOR].Load[/FONT]
[FONT="] lblStatus.Location = [COLOR=blue]New[/COLOR] Point(16, 24)[/FONT]
[FONT="] lblStatus.Text = [COLOR=maroon]"Waiting"[/COLOR][/FONT]
[FONT="] butDoStuff.Location = [COLOR=blue]New[/COLOR] Point(16, 56)[/FONT]
[FONT="] butDoStuff.Size = [COLOR=blue]New[/COLOR] Size(160, 40)[/FONT]
[FONT="] butDoStuff.Text = [COLOR=maroon]"Do Large Query"[/COLOR][/FONT]
[FONT="] [COLOR=blue]Me[/COLOR].Controls.Add(lblStatus)[/FONT]
[FONT="] [COLOR=blue]Me[/COLOR].Controls.Add(butDoStuff)[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]Sub[/COLOR] butDoStuff_Click([COLOR=blue]ByVal[/COLOR] sender [COLOR=blue]As[/COLOR] System.Object, [COLOR=blue]ByVal[/COLOR] e [COLOR=blue]As[/COLOR] System.EventArgs) [COLOR=blue]Handles[/COLOR] butDoStuff.Click[/FONT]
[FONT="] lblStatus.Text = [COLOR=maroon]"Started"[/COLOR][/FONT]
[FONT="] [COLOR=green]'start doing a query[/COLOR][/FONT]
[FONT="] AsyncMan.StartAsync()[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]Sub[/COLOR] AsyncFinished() [COLOR=blue]Handles[/COLOR] AsyncMan.OnAsyncComplete[/FONT]
[FONT="] lblStatus.Text = [COLOR=maroon]"Finished"[/COLOR][/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[COLOR=blue][FONT="]End[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR][/FONT]
[COLOR=blue][FONT="]Public[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR] AsyncManager[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]WithEvents[/COLOR] dba [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] DBAccess()[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] [COLOR=blue]Delegate[/COLOR] [COLOR=blue]Sub[/COLOR] LargeQueryCompleteDelegate[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] LargeQueryCompleteEvent [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] LargeQueryCompleteDelegate([COLOR=blue]AddressOf[/COLOR] AsyncComplete)[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] AsyncResult [COLOR=blue]As[/COLOR] IAsyncResult [COLOR=green]'result for async thread call[/COLOR][/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Event[/COLOR] OnAsyncComplete[/FONT]
[FONT="] [COLOR=blue]Private[/COLOR] Parent [COLOR=blue]As[/COLOR] Control [COLOR=green]'parent control that runs in UI thread[/COLOR][/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Sub[/COLOR] [COLOR=blue]New[/COLOR]([COLOR=blue]ByRef[/COLOR] ParentForm [COLOR=blue]As[/COLOR] Control)[/FONT]
[FONT="] [COLOR=blue]Me[/COLOR].Parent = ParentForm[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Sub[/COLOR] StartAsync()[/FONT]
[FONT="] [COLOR=blue]Dim[/COLOR] t [COLOR=blue]As[/COLOR] [COLOR=blue]New[/COLOR] Threading.Thread([COLOR=blue]AddressOf[/COLOR] dba.LargeQuery)[/FONT]
[FONT="] t.Start()[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Sub[/COLOR] AsyncFinished() [COLOR=blue]Handles[/COLOR] dba.OnQueryFinished[/FONT]
[FONT="] [COLOR=green]'***** INVOKE EVENT ON MAIN THREAD *****'[/COLOR][/FONT]
[FONT="] [COLOR=green]'***** OTHER THREAD WILL FINISH *****'[/COLOR][/FONT]
[FONT="] AsyncResult = Parent.BeginInvoke(LargeQueryCompleteEvent)[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Sub[/COLOR] AsyncComplete()[/FONT]
[FONT="] [COLOR=green]'***** MOVE ACCESS FILE TO SHARED DRIVE *****'[/COLOR][/FONT]
[FONT="] [COLOR=green]'***** ACCESS FILE DELETED NOW *****'[/COLOR][/FONT]
[FONT="] Parent.EndInvoke([COLOR=blue]Me[/COLOR].AsyncResult)[/FONT]
[FONT="] [COLOR=blue]RaiseEvent[/COLOR] OnAsyncComplete[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[COLOR=blue][FONT="]End[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR][/FONT]
[COLOR=blue][FONT="]Public[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR] DBAccess[/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Event[/COLOR] OnQueryFinished[/FONT]
[FONT="] [COLOR=blue]Public[/COLOR] [COLOR=blue]Sub[/COLOR] LargeQuery()[/FONT]
[FONT="] Threading.Thread.Sleep(3000)[/FONT]
[FONT="] [COLOR=green]'***** ACCESS FILE CREATED HERE *****'[/COLOR][/FONT]
[FONT="] [COLOR=green]'***** ACCESS FILE LOCK IS HELD BY THIS THREAD *****'[/COLOR][/FONT]
[FONT="] [COLOR=blue]RaiseEvent[/COLOR] OnQueryFinished[/FONT]
[FONT="] [COLOR=blue]End[/COLOR] [COLOR=blue]Sub[/COLOR][/FONT]
[COLOR=blue][FONT="]End[/FONT][/COLOR][FONT="] [COLOR=blue]Class[/COLOR][/FONT]