Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » DBISAM Technical Support » Support Forums » DBISAM General » View Thread |
Messages 1 to 5 of 5 total |
threading and data-aware controls |
Fri, Mar 30 2007 2:48 PM | Permanent Link |
Jason Lee | Hi All,
I'm rearranging some of my threading stuff in an app. How do I run a query that takes a few minutes in a background thread and then display its results in a data-aware grid when it's done. I'd prefer the thread to terminate when finished, but this is not absolutely required. Can I create a memory table in a thread that can be been by my main VCL thread? Using D7, DBISAM V4 C/S TIA, Jason Lee |
Sat, Mar 31 2007 5:28 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Jason
Its not difficult. I'm stuck some code below to give you a bit of an idea but essentially, as long as you only run the query from the form 1. Declare the thread class before your form class 2. Add a private variable of the thread class type to the form 3. Drop a TDBISAMQuery component on the form 4. Create a procedure as part of the class declaration to handle the return message 5. Run the query ... thrdFinder := TQThread.Create(Finder, Self.Handle); Roy Lambert //Thread class declaration - very simple type TQThread = class(TThread) private FSearcher: TDBISAMQuery; FRespondTo: HWND; protected procedure Execute; override; public constructor Create(SearchQry: TDBISAMQuery; RespondTo: HWND); end; constructor TQThread.Create(SearchQry: TDBISAMQuery; RespondTo: HWND); begin inherited Create(True); // Create thread in a suspendend state so we can prepare vars FSearcher := SearchQry; //Set up local query var to be executed. FRespondTo := RespondTo; FreeOnTerminate := True; //Free thread when finished executing Resume; end; procedure TQThread.Execute; begin FSearcher.ExecSQL; //Perform the query PostMessage(FRespondTo, srchDone, 0, 0); end; procedure TMNSearchForm.SearchComplete(var Message: TMessage); begin ResultsTab.TabVisible := True; SearchRunning := False; Progress.Progress := 0; Progress.Visible := False; ResultsTab.TabVisible := True; ResultsTab.Caption := 'Results: ' + IntToStr(Finder.RecordCount) + ' items found'; SpeedButton1.Visible := True; dsFinder.DataSet := Finder; PageControl1.ActivePage := ResultsTab; Panel1.Visible := False; if Finder.RecordCount > 0 then FinderAfterScroll(Finder) end; |
Sat, Mar 31 2007 12:19 PM | Permanent Link |
Jason Lee | Roy,
Great, thank you and I'll give it a try, but this begs the question: doesn't this break the rules for DBISAM and multithreading? (i.e. separate session, database, tables, queries, etc.) Thanks again, Jason Lee Roy Lambert wrote: > Jason > > > Its not difficult. I'm stuck some code below to give you a bit of an idea but essentially, as long as you only run the query from the form > > 1. Declare the thread class before your form class > 2. Add a private variable of the thread class type to the form > 3. Drop a TDBISAMQuery component on the form > 4. Create a procedure as part of the class declaration to handle the return message > 5. Run the query ... thrdFinder := TQThread.Create(Finder, Self.Handle); > > > Roy Lambert > > > > > //Thread class declaration - very simple > type > TQThread = class(TThread) > private > FSearcher: TDBISAMQuery; > FRespondTo: HWND; > protected > procedure Execute; override; > public > constructor Create(SearchQry: TDBISAMQuery; RespondTo: HWND); > end; > > constructor TQThread.Create(SearchQry: TDBISAMQuery; RespondTo: HWND); > begin > inherited Create(True); // Create thread in a suspendend state so we can prepare vars > FSearcher := SearchQry; //Set up local query var to be executed. > FRespondTo := RespondTo; > FreeOnTerminate := True; //Free thread when finished executing > Resume; > end; > > procedure TQThread.Execute; > begin > FSearcher.ExecSQL; //Perform the query > PostMessage(FRespondTo, srchDone, 0, 0); > end; > > procedure TMNSearchForm.SearchComplete(var Message: TMessage); > begin > ResultsTab.TabVisible := True; > SearchRunning := False; > Progress.Progress := 0; > Progress.Visible := False; > ResultsTab.TabVisible := True; > ResultsTab.Caption := 'Results: ' + IntToStr(Finder.RecordCount) + ' items found'; > SpeedButton1.Visible := True; > dsFinder.DataSet := Finder; > PageControl1.ActivePage := ResultsTab; > Panel1.Visible := False; > if Finder.RecordCount > 0 > then FinderAfterScroll(Finder) > end; |
Sun, Apr 1 2007 5:17 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Jason
The reason for creating separate sessions, tables, queries etc is so that DBISAM / Delphi knows that its separate and will apply locking etc as necessary and so that memory doesn't get overwritten. If NOTHING else uses the query then you're safe. In my app, and condoned by The Great Tim I also have an OnProgress event attached to the query updating a progress bar. Roy Lambert |
Tue, Apr 3 2007 9:21 AM | Permanent Link |
Tim Young [Elevate Software] Elevate Software, Inc. timyoung@elevatesoft.com | Jason,
<< Great, thank you and I'll give it a try, but this begs the question: doesn't this break the rules for DBISAM and multithreading? (i.e. separate session, database, tables, queries, etc.) >> You can break the DBISAM threading rules if you know what you're doing and can guarantee that only one thread will be accessing a particular DBISAM component at the same time. -- Tim Young Elevate Software www.elevatesoft.com |
This web page was last updated on Thursday, March 28, 2024 at 06:05 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |