Re: Thread-safe Collection
- From: "Tony Proctor" <tony_proctor@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx>
- Date: Sat, 15 Sep 2007 13:24:49 +0100
Thanks for all this Olaf.
You're right about the Application object. I hadn't even considered that
because all the Microsoft documentation is adamant that it should not be
used for storing STA objects because of cross-thread issues, and the
supposed serious impact on the performance of the web server.
In my most important case, the dictionary is a global read-only cache.
Obviously it would have to be populated by one of the threads during
startup, but after that it would only be supporting multiple readers. Hence,
it would still need read-locks and write-locks to be safe but the write-lock
contention would be almost non-existent.
Ideally, I wanted the dictionary items in a common memory store (to avoid
the VM size getting multiplied per thread), but still allow multiple
concurrent readers for maximum performance
I'll investigate your suggestions as soon as I can
Tony Proctor
"Schmidt" <sss@xxxxxxxxx> wrote in message
news:%23MnHBDt9HHA.5160@xxxxxxxxxxxxxxxxxxxxxxx
"Tony Proctor" <tony_proctor@xxxxxxxxxxxxxxxxxxxxxxxxxxxxx> schrieb im
Newsbeitrag news:udOcLNi9HHA.5404@xxxxxxxxxxxxxxxxxxxxxxx
I thought about this a little more Olaf.What do you mean with "these Objects".
You cannot guarantee the performance of these objects
since it depends to some extent on how their
memory is spread out, and how you access it.
If you pin a singleton somewhere, then this singleton-
class implements only one (private) Collection internally.
And the marshaled performance I've measured is
of course only related to access-attempts to the
*interface* of this singleton-object.
The additional time needed for accessing the internal
dictionary-based Cache-Object would have to be
respected/added of course - but these "extra-costs" would
you see even in an unmarshaled approach, wich uses
CriticalSections instead of the builtin "serialized access to
a shared resource", wich OLE-Marshalling offers "for free".
A different story would be, if your shared resource is more
static regarding its content and should allow parallel reading
from multiple STAs - but that's what Databases are built for.
If you want to have fast parallel reads from multiple STAs,
and secure, serialized writes you can use e.g. SQLite, wich
has low memory-footprint and offers optimized search-strategies
on indexed Data and even full-text-table-searches.
In my thinking about a fast, singleton-internal Dictionary-Object
I would lock even the Read-Direction for security-reasons,
because a parallel Adding, whilst another STA reads Data
could cause inpredictable results.
You would have to decide/measure, if a fast, but serialized
Dictionary-Access performs better, than access against
a DataBase-Connection, wich could process Read-Requests
in parallel from multiple STAs, but has somewhat more
overhead compared with a "Singleton-Dictionary".
Performance isn't bad usingYou could use e.g. my much (regarding indexed access)
only hashing (up to a limit) but indexing is very bad.
faster Sorted-Dictionary implementation as the private
Object inside your Singleton-Class.
Also, the type of singleton I would have to use wouldYou mean, the shared singleton-object would have to
have to be process-specific, not machine-wide, and
not specific only to the class being instantiated.
be hosted inside the IIS-Process. IIRC you can "pin"
such an singleton-object using ASP in the global
Application-Cache:
Application.Lock
Set Application("YourKey") = CreateObject("My.SingletonCache")
Application.UnLock
or better yet in
Application_OnStart of the Global.asa
Cleanup/Shutdown then in:
Application_OnEnd
retrieving the marshaled Singleton:
Set MySingletonCache = Application("YourKey")
Since "transactions" only work on Call-Basis with
Ole-Marshalling you should take that into respect
and avoid multiple interface-calls.
E.g. something like this should be avoided:
If Not MySingletonCache.EntryExists(Key) Then
MySingletonCache.AddEntry Key, Entry
End If
Or even worse: For Each-Enumerations...
All those multiple calls have to be encapsulated internally.
Instead you will have to handle it in one single call:
MySingletonCache.AddEntryIfNotExists Key, Entry
Only this way you can be sure, that the Marshaller
blocks other STAs - meaning: you have Transaction-safety -
but only at "Single-Call-Level".
With a normal VB project you'd do this via static data in aYou can share memory relative easy between threaded
Module, but there is no shared data in a multithreaded VB
context.
STAs in VB using SafeArray-Pointers.
Of course you have to regulate the access to such shared
memory-Resources with your own Locking-mechanisms
using CriticalSections then.
If you want, I can write an example for you, wich shares
a SortedDictionary-Instance between multiple STAs
in a standard VB-Exe, but regarding your IIS-host I'd
recommend the *marshaled* Singleton-approach
(or alternatively a lightweight DB-Engine) anyway.
Olaf
.
- Follow-Ups:
- Re: Thread-safe Collection
- From: Schmidt
- Re: Thread-safe Collection
- References:
- Thread-safe Collection
- From: Tony Proctor
- Re: Thread-safe Collection
- From: Schmidt
- Re: Thread-safe Collection
- From: Tony Proctor
- Re: Thread-safe Collection
- From: Schmidt
- Re: Thread-safe Collection
- From: Tony Proctor
- Re: Thread-safe Collection
- From: Schmidt
- Re: Thread-safe Collection
- From: Tony Proctor
- Re: Thread-safe Collection
- From: Schmidt
- Thread-safe Collection
- Prev by Date: Re: Problem with xmlhttp
- Next by Date: Re: Thread-safe Collection
- Previous by thread: Re: Thread-safe Collection
- Next by thread: Re: Thread-safe Collection
- Index(es):
Relevant Pages
|