Icon View Thread

The following is the text of the current message along with any replies.
Messages 21 to 30 of 32 total
Thread Writing a function that queries data in Thread
Mon, May 19 2014 10:52 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate 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 AMPermanent Link

Raul

Team Elevate 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 PMPermanent 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 AMPermanent Link

Raul

Team Elevate 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 PMPermanent 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' Smiley 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. Smile

Cheers

Adam.
Thu, May 22 2014 5:26 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate 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 PMPermanent Link

Raul

Team Elevate 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' Smiley 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 PMPermanent 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 PMPermanent 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). Smile

Thanks for your help Raul! Have a great weekend!

Adam.
Fri, May 23 2014 4:56 AMPermanent Link

Roy Lambert

NLH Associates

Team Elevate 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 PagePage 3 of 4Next Page »
Jump to Page:  1 2 3 4
Image