locking objects

  • Thread starter Thread starter Pohihihi
  • Start date Start date
P

Pohihihi

Suppose I have a method (MethodA()) and I do some data access in it (e.g. get results from DB SPs on some select query). This method is fired via a event (say button click). Now if I keep on clicking the button and MethodA() is kept on called what happen to the calls that are looking at the lock while the first request is still processing the request from DB. In other words those request do busy wait automatically or they just ignore the request and do nothing ?
 
Pohihihi said:
Suppose I have a method (MethodA()) and I do some data access in it
(e.g. get results from DB SPs on some select query). This method is
fired via a event (say button click). Now if I keep on clicking the
button and MethodA() is kept on called what happen to the calls that
are looking at the lock while the first request is still processing
the request from DB. In other words those request do busy wait
automatically or they just ignore the request and do nothing ?

If it's all in the UI thread, the click events are just waiting in the
message queue. They won't get processed until the UI thread looks for
events again, which (unless you call Application.DoEvents, which I
don't suggest) will be when your event has finished firing.

This is why you shouldn't do anything time-consuming (like DB access)
in the UI thread. Your UI effectively locks up during that time.
 
Basically I am creating thread to access db and load a dataset but the part
when dataset is filled i am putting a lock (in case a next request). this is
happening when user scroll through months by clicking month calendar to see
data related to date. now I can't load few months either side to save some
data access as there are tons of records and it will eat big amount of
memory on client to hold that data. so what I do is to handle change event
and fill the dataset with information for visible month. but it is possible
that user keep on clicking month to scroll to next month. one thing i am
thinking is that to wait before accessing db to be sure that user is not
clicking any more but then question comes is how much time to wait. better
option for now is that i load data anyways. so for that accessing db part
comes as thread for every request (a new thread every request). now this
might create problem of its own in case delay is too long and too many
threads are holding in memory. bottom line is what could be a better option.
 
I think creating a new thread for each request is not the recommended
way since you don't know how many requests there might be. That harms
the app's scalability very much. The second option to cache data (for
example, for the next month) sounds better. The UI should also provides
an easy way for user to jump to a specific month instead of constantly
click "next" or something like that. As always, measure to see if there
is really any performance gain when you try an improvement.

Regarding "lock" (that is, the Monitor class), once one thread
successfully acquire a lock on an object, other threads requesting lock
on the same object will have to busy wait (no timeout applied) until
the owning thread release it.

Thi
 
Pohihihi said:
Basically I am creating thread to access db and load a dataset but the part
when dataset is filled i am putting a lock (in case a next request).

Note that if this is within a Windows Forms app and the dataset is
bound to a control, you should only do the filling within the UI
thread.
this is
happening when user scroll through months by clicking month calendar to see
data related to date. now I can't load few months either side to save some
data access as there are tons of records and it will eat big amount of
memory on client to hold that data. so what I do is to handle change event
and fill the dataset with information for visible month.

So are you creating the new thread within the change event?
but it is possible
that user keep on clicking month to scroll to next month. one thing i am
thinking is that to wait before accessing db to be sure that user is not
clicking any more but then question comes is how much time to wait. better
option for now is that i load data anyways. so for that accessing db part
comes as thread for every request (a new thread every request). now this
might create problem of its own in case delay is too long and too many
threads are holding in memory. bottom line is what could be a better
option.

Well, if you're using a SqlCommand, you could cancel the current
command if one is executing when the user clicks. That's the most
efficient way of doing things without waiting to see if there are more
clicks coming.

As Truong said, the lock statement itself doesn't have a timeout.
However, if you want locking with timeouts, it's quite possible to do
it - see http://www.pobox.com/~skeet/csharp/threads/alternative.shtml
I'm hoping to upload a new version of MiscUtil with deadlock detection
in the next day or two - the code is written, it just needs potentially
renaming and documenting :)
 
Truong Hong Thi said:
I think creating a new thread for each request is not the recommended
way since you don't know how many requests there might be. That harms
the app's scalability very much.

yes, I am thinking in the same direction. More over user computer is limited
to the amount of RAM they can have.
The second option to cache data (for
example, for the next month) sounds better.

I can pull 3 months (one each way) but again the problem is limited amount
of memory. On a avg one month worth of data goes anywhere between 15000 to
25000 records (many have blob). It will kill user machine, which I guess
will not have more than 128MB of RAM shared between other apps (e.g. word,
excel etc).
The UI should also provides
an easy way for user to jump to a specific month instead of constantly
click "next" or something like that.

There are 2 options, direct jump to the month and click next. Cause of UI
guidelines I can't take away next from them. So basically I got to find a
way to live with it.
As always, measure to see if there
is really any performance gain when you try an improvement.

Performance is great if I pull the data for 3 months locally and do a
forward cacha for future request. DB responce time is bottleneck here. SPs
do not return records fast, more because records are mixed of text and blob
and DB is a very busy DB with these kind of requests.
Regarding "lock" (that is, the Monitor class), once one thread
successfully acquire a lock on an object, other threads requesting lock
on the same object will have to busy wait (no timeout applied) until
the owning thread release it.

That is not good, it might turn into a big deadlock.
 
Jon Skeet said:
Note that if this is within a Windows Forms app and the dataset is
bound to a control, you should only do the filling within the UI
thread.

Yes it is connected with 3rd party control.

........>> and fill the dataset with information for visible month.
So are you creating the new thread within the change event?

DAL has method that I call to fill ds in UI thread but via creating a thread
to access db which in turn returns and fills a ds and prompts a event to
fill final ds. Little extra work but this is were I have lock to fill final
ds.


..........
Well, if you're using a SqlCommand, you could cancel the current
command if one is executing when the user clicks. That's the most
efficient way of doing things without waiting to see if there are more
clicks coming.

I don't have control over sqlcommand statement. It is a method to access db
in DAL and I pass params. Non of the method supports cancellation. It will
be a good way but is there a way all together to avoid network traffic by
sending only that request which will be consumed on return. I am kind of
thinking that I am stuck with the option of waiting for say 3 second before
sending the request but I also understand that this is a limited solution
for my problem. I guess my thought process is kind of stuck with this and
limiting me to think more.


As Truong said, the lock statement itself doesn't have a timeout.
However, if you want locking with timeouts, it's quite possible to do
it - see http://www.pobox.com/~skeet/csharp/threads/alternative.shtml
I'm hoping to upload a new version of MiscUtil with deadlock detection
in the next day or two - the code is written, it just needs potentially
renaming and documenting :)

I will surely use it. Are you going to open the code as well?
 
Pohihihi said:
Yes it is connected with 3rd party control.

Okay - in that case you need to be really careful, I'm afraid.
.......>> and fill the dataset with information for visible month.

DAL has method that I call to fill ds in UI thread but via creating a thread
to access db which in turn returns and fills a ds and prompts a event to
fill final ds. Little extra work but this is were I have lock to fill final
ds.

That's unfortunate.
.........


I don't have control over sqlcommand statement. It is a method to access db
in DAL and I pass params. Non of the method supports cancellation.

That's even more unfortunate...
It will be a good way but is there a way all together to avoid
network traffic by sending only that request which will be consumed
on return. I am kind of thinking that I am stuck with the option of
waiting for say 3 second before sending the request but I also
understand that this is a limited solution for my problem. I guess my
thought process is kind of stuck with this and limiting me to think
more.

I think it's more that the API you're using is limited, unfortunately.
I will surely use it. Are you going to open the code as well?

It's already open source.
 
Thank you.


Jon Skeet said:
Okay - in that case you need to be really careful, I'm afraid.


That's unfortunate.


That's even more unfortunate...


I think it's more that the API you're using is limited, unfortunately.


It's already open source.
 
Back
Top