Login ProductsSalesSupportDownloadsAbout |
Home » Technical Support » DBISAM Technical Support » Support Forums » DBISAM General » View Thread |
Messages 21 to 30 of 32 total |
Writing a function that queries data in Thread |
Mon, May 19 2014 10:52 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Raul
>- DoHandleException thing is not needed as it is - that is for form >window. In general execute function is where the exception handling is >needed > >- OnTerminate - don't do this. it's already handled for you by tthread >- also don't call OnTerminate in execute - again done for you by base class Weirdly enough with Adam's design the thread didn't call its OnTerminate event. I put in a showmessage just to see and it only fired once. Roy Lambert |
Mon, May 19 2014 11:21 AM | Permanent Link |
Raul Team Elevate | On 5/19/2014 10:52 AM, Roy Lambert wrote:
> Weirdly enough with Adam's design the thread didn't call its OnTerminate event. I put in a showmessage just to see and it only fired once. I'm sure it did but there was nothing for it to call. Adam had declared a property OnTerminate as well as a variable FOnTerminate in his thread thus hiding TThread implementation so no event handler even got assigned to the real thread. He was also calling OnTerminate from execute which is not thread safe at all since it called his function and did not properly synchronize to the main thread (as the TThread OnTerminate would do) Raul |
Mon, May 19 2014 7:27 PM | Permanent Link |
Adam H. | Thanks Raul, Roy and Matthew,
I've checked out the two examples. Thanks for taking the time to do them up Raul! Version a is much easier for me to get my head around, but I accept your recommendations that version b is the 'better' approach even though I'm not comfortable with my knowledge on messages and pointers. I'll give b a try within my real application. My main concern is putting in code I don't fully understand what's happening to debug if problems arise but I guess the best way to learn is to start implementing it. I also accept and understand your points on passing the Session and Database components. I guess if I start coding this way, then it's only a matter of time until it catches up with me down the track, so I'm better off to start doing it right and I won't pick up bad habits. Thanks again for the help. Cheers Adam. |
Wed, May 21 2014 10:03 AM | Permanent Link |
Raul Team Elevate | On 5/19/2014 7:27 PM, Adam H. wrote:
> Version a is much easier for me to get my head around, but I accept your > recommendations that version b is the 'better' approach even though I'm > not comfortable with my knowledge on messages and pointers. Depending on your needs version A might be just fine for you. However it does not scale as well and is a lot less generic than version B. I also don't like the fact that ver A is coupled - you're accessing thread variables direct - meaning that it's tied with the design too much and might lead to subtle bugs down the line due to this. Note that using pointers (in this case just 1 dynamic record allocation) is purely optional. I used it to show how one could send back a record with data elements. However if you look at the PostMessage itself it actually takes 3 int type parameters (Cardinal for Msg, and longints for Wparam and LParam) so if you're uncomfortable with the pointers and are willing to use just int values then just send int values back and then in main thread build a message (what Roy suggested to send back message id and then look up the associated text string). > I'll give b a try within my real application. My main concern is putting > in code I don't fully understand what's happening to debug if problems > arise but I guess the best way to learn is to start implementing it. What parts are you unsure of? To be honest i find the ver B to be lot clearer (and cleaner) than ver A. Ver A relies on synchronize which itself uses critical section etc. Ver B uses a Windows OS level basic thread message passing - so very clean and requires very minimum code to handle. Ver B is almost as complex as it conceptually ever gets (only thing missing is for the main thread to send messages to the work thread and work thread to handle them in execute loop). Raul |
Wed, May 21 2014 10:29 PM | Permanent Link |
Adam H. | Hi Raul,
> Depending on your needs version A might be just fine for you. However it > does not scale as well and is a lot less generic than version B. I also > don't like the fact that ver A is coupled - you're accessing thread > variables direct - meaning that it's tied with the design too much and > might lead to subtle bugs down the line due to this. Since version B is more scalable - I'd prefer to work on using (and becoming more familiar) with this approach. I accept the wisdom of those who have gone before me. <vbg> > Note that using pointers (in this case just 1 dynamic record allocation) > is purely optional. I used it to show how one could send back a record > with data elements. However if you look at the PostMessage itself it > actually takes 3 int type parameters (Cardinal for Msg, and longints for > Wparam and LParam) so if you're uncomfortable with the pointers and are > willing to use just int values then just send int values back and then > in main thread build a message (what Roy suggested to send back message > id and then look up the associated text string). Unfortunately the real data I want to send back isn't just a set of messages - it could be anything which comes from the data that is queried, so I'm going to need to store data (in my list in a TStringsList) and access it from the main thread. The only way seems to be with pointers. I guess once again, time for me to become more familiar with them. >> I'll give b a try within my real application. My main concern is putting >> in code I don't fully understand what's happening to debug if problems >> arise but I guess the best way to learn is to start implementing it. > > What parts are you unsure of? To be honest i find the ver B to be lot > clearer (and cleaner) than ver A. Pretty much pointers, handles and messages. (All the things that aren't in version 'A' I can sort of follow using the example if I look over it a few times, but if you asked me to design a basic hello world application that used pointers, handles and messages as an example from scratch I'd have to go searching again to find an example to copy. > Ver B is almost as complex as it conceptually ever gets (only > thing missing is for the main thread to send messages to the work thread > and work thread to handle them in execute loop). OK - I thought about that once, and now my head is spinning. I think I'll just get used to what I need at the moment, and then maybe revisit that later. Cheers Adam. |
Thu, May 22 2014 5:26 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Adam
>Since version B is more scalable - I'd prefer to work on using (and >becoming more familiar) with this approach. I accept the wisdom of those >who have gone before me. <vbg> Good choice - its definitely the way to go. >Unfortunately the real data I want to send back isn't just a set of >messages - it could be anything which comes from the data that is >queried, so I'm going to need to store data (in my list in a >TStringsList) and access it from the main thread. The only way seems to >be with pointers. There are many ways to pass data back to the calling thread. If its non-structured and non-meaningful (in a program operation sense rather than a human interaction way) then yes you can't rely on just passing numbers back. If you don't like pointers, allocating memory etc (I don't) then here are a few other thoughts: 1. you can write a small file to disk and then read it from there 2. there are various forms of inter-process communication (eg tcp/ip) that could be used - probably a nastier experience than using pointers in my opinion 3. since you're using a database and will be accessing that database in the thread you could use that - set up a small table either disk or memory - its something you already understand and if properly isloated dead safe 4. synchronise can be used at the end If you go down the get / free memory pointer route then you have a choice of methods. I'd probably use a stringlist in the thread, then, before sending the message dump the stringlist.text into a string variable, use Raul's code for passing the string and convert back to a stringlist at the other side. The other option is to create the stringlist in the thread, load it, pass the pointer to the stringlist over in the postmessage then in the receiving thread use that pointer by casting eg TStringList(msg.wParam) and finally remember to free it in the receiving thread. Roy Lambert |
Thu, May 22 2014 4:09 PM | Permanent Link |
Raul Team Elevate | On 5/21/2014 10:29 PM, Adam H. wrote:
> Unfortunately the real data I want to send back isn't just a set of > messages - it could be anything which comes from the data that is > queried, so I'm going to need to store data (in my list in a > TStringsList) and access it from the main thread. The only way seems to > be with pointers. > > I guess once again, time for me to become more familiar with them. Note that you can send as many messages to main thread as you want. Depending on amount of data and other things it might be easier to just post the data as it becomes available to main thread and maintain the stringlist there. > Pretty much pointers, handles and messages. (All the things that aren't > in version 'A' I can sort of follow using the example if I look > over it a few times, but if you asked me to design a basic hello world > application that used pointers, handles and messages as an example from > scratch I'd have to go searching again to find an example to copy. > You're actually using pointers all the time. There is no real difference between "SomeObject.Create() / SomeObject.Free()" and "New(rec) / Dispose (rec)". Both are pointers - one just happens to point to instance of dynamically created class and other to record. If you prefer classes then you can just create your own and pass that around and just remember to create in worker thread and free in main thread. Handles are OS specific structures but in this case you just need to remember how to (de)allocate a window handle. Messages again are just numbers to uniquely identify a message Raul |
Thu, May 22 2014 8:30 PM | Permanent Link |
Adam H. | Hi Roy,
> If you go down the get / free memory pointer route then you have a choice of methods. I'd probably use a stringlist in the thread, then, before sending the message dump the stringlist.text into a string variable, use Raul's code for passing the string and convert back to a stringlist at the other side. The other option is to create the stringlist in the thread, load it, pass the pointer to the stringlist over in the postmessage then in the receiving thread use that pointer by casting eg TStringList(msg.wParam) and finally remember to free it in the receiving thread. Interesting. Is there any reason you wouldn't just use a pointer to the actual TStringList? This is what I have done and it seems to be working for me. (ie, use Raul's approach but instead of a String variable, using a TStringList)? If I don't talk to you before hand - have a great weekend, and thanks again for your assistance! Adam. |
Thu, May 22 2014 8:32 PM | Permanent Link |
Adam H. | Hi Raul,
Thanks for your help... > Note that you can send as many messages to main thread as you want. > Depending on amount of data and other things it might be easier to just > post the data as it becomes available to main thread and maintain the > stringlist there. I'm beginning to think I should be becoming more familiar with messages. They seem to be safer (ie, if the form isn't there anymore, it won't Access Violate out). > Handles are OS specific structures but in this case you just need to > remember how to (de)allocate a window handle. Messages again are just > numbers to uniquely identify a message I guess my problem isn't with the concept of pointers - just getting my head around to the code required to use them (correctly). Thanks for your help Raul! Have a great weekend! Adam. |
Fri, May 23 2014 4:56 AM | Permanent Link |
Roy Lambert NLH Associates Team Elevate | Adam
>Interesting. Is there any reason you wouldn't just use a pointer to the >actual TStringList? This is what I have done and it seems to be working >for me. (ie, use Raul's approach but instead of a String variable, using >a TStringList)? Its fine as long as you remember to NOT free the stringlist in the thread and remember to never access the stringlist in the main thread until the providing thread has finished. I prefer the other approach because I like to see the create and free in the same place or at least the same unit. I don't have the same hang up about direct memory allocation / releasing. Roy Lambert |
« Previous Page | Page 3 of 4 | Next Page » |
Jump to Page: 1 2 3 4 |
This web page was last updated on Tuesday, April 30, 2024 at 03:55 PM | Privacy PolicySite Map © 2024 Elevate Software, Inc. All Rights Reserved Questions or comments ? E-mail us at info@elevatesoft.com |