Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / Languages / C# / March 2008

Tip: Looking for answers? Try searching our database.

Making a base class' methods thread safe

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
Steve K. - 02 Mar 2008 23:19 GMT
I am creating several data access objects that all derive from a base class
which implements the web service access functionality.

For example (fake code):
<code>
public class DAOBase
{
   protected List<TType> Search<TType>(string nameHint)
   {
       //  code to login to web service session, execute search
       //  and return the result.
       return new List<TType>();
   }
}

public class CustomerDAO : DAOBase
{
   public List<Customer> GetCustomer(string name)
   {
       return base.Search<Customer>(name);
   }
}

public class OrderDAO : DAOBase
{
   public List<Order> GetCustomerOrders(string name)
   {
       //  some code that will execute a search using the DAOBase
       //  Search method
       return null;
   }
}
</code>

The web service access exposed in DAOBase is session based and I can only
have one session at a time.  In other words, I can't run two searches at the
same time, they must be synchronous.
Once I've logged in (expensive operation) I want to reuse the same session
for all subsequent requests.

I'm thinking of the different ways that I can accomplish this.  One idea is
to refactor my code so that my web service functionality is in a new
Singleton class, then the base class would have an instance of this
singleton.  This way I could keep my session alive in the singleton and all
concrete objects would access the singleton through the base class.

This would give me thread safety, or, more accurately it won't prevent two
web service requests from being invoked on top of each other.  If this
happens, the session will be killed. (bad)

I need to implement a queue to handle the web service request(s) from the
various concrete DAO classes, most likely using the command pattern and
wrapping all request in an object that can be enqueued.

So that is my first and only real idea to solve the issue.  Another idea
that is fluttering around in my head is to keep the web service access in
the base class but make the methods static.  This will give me the single
session shared with all concrete objects but introduces thread safety issues
(I think).

I would really like to hear what any of you think, before I start modifying
(and breaking) my code all over the place I thought I would ask first to see
if I'm on the right track.

Thanks for any input,
Steve
Marc Gravell - 03 Mar 2008 05:30 GMT
What is your server setup? You mention session, so I'm guessing it is
fairly simple (1 server?) [session doesn't scale "out" very well].. in
which case WCF will offer synchronization at the server for free.

Alternatively, WCF might also provide options at the client to perform
sync - in particular I'm thinking about custom behaviors and
listeners. I've used such to update a session token from the WCF
headers before, but it could just as easily be doing a Monitor.Enter/
Monitor.Exit on a static lock. However, in contrast - a WCF session is
very brittle - once it has errors (any fault) it should really be
destroyed; and "asmx" will suffer a similar fate if the server is
restarted. A better option may be to manage session *separately* to
the default session that WCF/asmx offer - perhaps a guid in a header
that the service can detect and read from a db [but which is islotated
from the comms stack].

Alterantively, you could use a form of factory / dependency injection
here... for instance, something like (where ILease<T> is just
IDisposable and offers the service via .Service):

using(ILease<MyService> svc = SomeFactory.GetLease<MyService>()) {
 // do a batch of things with svc
 svc.Service.Foo();
 string wossit = svc.Service.Bar("Fred", "Wilma");
}

In this usage, you could obtain the lock during GetLease(), and free
the lock during Dispose(). But I'm assuming the above would use
separate proxies for each GetLease(), so again you would need separate
session management.

(this type of setup works fine with WCF, as it is fairly easy to write
a WCF factory and custom plugins to tweak what happens; much harder
for asmx)

Just some thoughts...
Steve K. - 03 Mar 2008 05:49 GMT
Hi Marc,

Comments inline>>>

> What is your server setup? You mention session, so I'm guessing it is
> fairly simple (1 server?) [session doesn't scale "out" very well].. in
> which case WCF will offer synchronization at the server for free.

I'm not running the server, it's our "On Demand" web based ERP/CRM
application.  I'm pretty sure they are running Oracle on linux, but could be
wrong.

> Alternatively, WCF might also provide options at the client to perform
> sync - in particular I'm thinking about custom behaviors and
[quoted text clipped - 7 lines]
> that the service can detect and read from a db [but which is islotated
> from the comms stack].

This all sounds really cool, but I don't think it's an option for me (not my
server).  I shoud have mentioned that in the original post, apologies.

> Alterantively, you could use a form of factory / dependency injection
> here... for instance, something like (where ILease<T> is just
[quoted text clipped - 5 lines]
>  string wossit = svc.Service.Bar("Fred", "Wilma");
> }

Interesting.  You suggest the Factory to support multiple service objects?
In my case, I have only the one service I'm working with, so I don't think I
would need a factory.

> In this usage, you could obtain the lock during GetLease(), and free
> the lock during Dispose(). But I'm assuming the above would use
[quoted text clipped - 6 lines]
>
> Just some thoughts...

I suspect I might have sent you in the wrong direction with my original
post.  I'm interested in find a solution on the client side that will allow
me to share a single session between many objects.

I'm trying to think of another way to phrase it but can't really.
I will tinker around mocking up some pseudo code to illustrate what I'm
trying to do and post later.

Thanks for the reply and suggestions, I wish I was in control of the service
so I could explore your suggestions, they sound slick!
-Steve
Mufaka - 03 Mar 2008 06:29 GMT
> The web service access exposed in DAOBase is session based and I can only
> have one session at a time.  In other words, I can't run two searches at the
> same time, they must be synchronous.
> Once I've logged in (expensive operation) I want to reuse the same session
> for all subsequent requests.

I think your session should be expanded on a little bit. Is this a
clients logged in session? And if so, how is this maintained on the
client? ie: is it an open socket or is it a login token retrieved after
a successful login?

If it's something like the latter, I'd hope that the server wouldn't
limit you to synchronous calls against that session. That seems very
restrictive.

If you do have this restriction, a Singleton Queue with a callback
delegate will probably work.
sklett - 03 Mar 2008 19:39 GMT
>> The web service access exposed in DAOBase is session based and I can only
>> have one session at a time.  In other words, I can't run two searches at
[quoted text clipped - 6 lines]
> it an open socket or is it a login token retrieved after a successful
> login?

Hi Mufaka,

This is a client logged in session.  The web service exposes a proxie which
represents the session to the web service.  It's this service (which
contains the session) that I need to keep alive and reuse for multiple
objects.  Sorry for the confusion.

> If it's something like the latter, I'd hope that the server wouldn't limit
> you to synchronous calls against that session. That seems very
> restrictive.

It is very restrictive, the web service vendor is VERY concerned about the
web service traffic and I think that by limiting the users to synchronous
calls they are attempting to "encourage" developers to design efficient
solutions ;0)

> If you do have this restriction, a Singleton Queue with a callback
> delegate will probably work.

This is what I was thinking as well.  The only question I have is if a
separate Singleton class is the way to go or if I should create the static
service functionality in the base class.
I'm going to do some experiments later.

Thanks for the suggestions and help,
Steve
Mufaka - 03 Mar 2008 20:30 GMT
>>> The web service access exposed in DAOBase is session based and I can only
>>> have one session at a time.  In other words, I can't run two searches at
[quoted text clipped - 33 lines]
> Thanks for the suggestions and help,
> Steve

Bleck :p

It's just a matter of preference I guess. My preference would be to
create a separate Singleton for testing and development purposes.

It also seems more natural to place this logic in a separate class
rather than having a base class manage the synchronous logic / session
state as well.

But, arguments can be made for the opposite as well.

Good luck with this. It's definitely an interesting problem to solve.

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.