• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 193
  • Last Modified:

Memory Question

Say I have a class that exposes a static hashtable
Class A
{
private hashtable hash;
public static hashtable MyHashtable
{
get
{
return hash;
}
}
}

In my other class B
I want to access that very same hashtable.

I just call A.MyHashTable

Now my Question is that if I create a Hashtable instance in my Class B such as :

Class B
{
private Hashtable myHash = A.MyHashTable;
}

Will this actually copy the entire MyHashTable structure to Class B's memory stack, or it will just store a pointer to the actually memory address that contains MyHashTable.

Is doing this and then use
myhash["myKey"]
more performant than calling
A.MyHashTable["myKey"]  

??

Thanks
0
lordiano
Asked:
lordiano
  • 6
  • 4
  • 2
  • +1
3 Solutions
 
BurntSkyCommented:
No, myHash in class "B" will contain a reference (FYI: there are no "pointers" in C#...sort of) to A.MyHashTable, not a copy of it.

March's issue of MSDN Magazine contained a rather hilarious "Editor's Note" about made up words like "performant."

The performance of the two statements you suggest are probably so close that any difference would be nearly impossible to detect.  In fact, I would probably argue that they perform exactly the same, as both require using one reference to point to the object (myHash references A.MyHashTable, while A.MyHashTable references A.)
0
 
gregoryyoungCommented:
I would argue that this is a very dangerous design when it comes to thread safety as there is nothing protecting the hashtable which is NOT threadsafe from multiple threads accessing it concurrently.

i would also argue that the following code is impossible

"private hashtable hash;
public static hashtable MyHashtable
{
get
{
return hash;
}
}
}"

as the member hash is an instance member and the property is static ...

Greg

0
 
lordianoAuthor Commented:
The private Hashtable hash; should be private static Hashtable hash;

My mistake for missing it.

0
Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

 
gregoryyoungCommented:
I figured :)

in general I would be very wary of this design though as you lose all control of being able to lock the hash table (unless you create a threadsafe derived class for the hashtable)
0
 
lordianoAuthor Commented:
How about if i do it this way

private static object syncObject = new object();

then in the public method to get my hashtable in Class A i do :

public static Hashtable MyHashTable
{
get
{
lock(syncObject)
{
return hash;
}
}
}

will this solve the thread issue?
0
 
Diego PazosCommented:
I don't think so. I guess you meant lock(hash), anyway.
By doing that, what you do is ensure no two threads can 'get' the hashtable simultaneously.
However, that doesn't keep two objects from getting the hashtable one at a time, and then access it simultaneously.

To prevent that, you should create a class that encapsulates the HashTable and provides some thread safety.
A very basic implementation could be:

class MyHashTable {
    Hashtable H;
    public MyHashTable() {
        H = new Hashtable();
    }

    public object this[object key] {
        get {
            lock (H) {
                return H[key];
            }
        }
        set {
            lock (H) {
                H[key] = value;
            }
        }
    }

    public void Add(object key, object value) {
        lock (H) {
            this[key] = value;
        }
    }

    public int Count() {
        lock (H) {
            return H.Count;
        }
    }
}

Hope that helps.
0
 
lordianoAuthor Commented:
Actually, I wont be doing any modification to the Hashtable. I will load up the necessary data the first time its being called and the content of the Hashtable will not be changed throughout the entire process.
Do i still need that?
0
 
BurntSkyCommented:
If you're not going to change anything inside the Hashtable then you don't need to worry anything.  Locking is only so that other threads can't modify an object until the first one is done.
0
 
Diego PazosCommented:
Then I guess not. The problems arise when, for example, a thread queries an object another thread is deleting, or maybe replacing.
As long as you can ensure that there will be no simultaneous querying and modification (be it changes or deletion), I guess you're safe.
0
 
gregoryyoungCommented:
I would just expose the synchronized version of the hashtable which is thread safe ...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemcollectionshashtableclasssynchronizedtopic.asp

in your static constructor ...

m_Hash = new HashTable().Synchronized

private static Hashtable m_Hash;
public static Hashtable Hash {
    get { return m_Hash; }
}

easy enough :) and it removes the worry of thread safety as all of these other suggestion do not since they are locking only on the return of the reference thus not making the operation atomic.

You should be ok to read a hashtable concurrently BUT it is not guarenteed by the framework (I prefer to error on the safe side)

Cheeers,

Greg

0
 
lordianoAuthor Commented:
Great, that sounds good.

By the way, I am initiating my Hashtable with ADO.NET from database.
That is, I am calling sproc and then use IDataReader and fill up my Hashtable with it.
The sproc simply returns a table of 2 columns, the 1st column would be the key and 2nd being the value.
This is how I am doing it now :

private static Hashtable hash;
private static object syncObject = new object();
public static hashtable MyHashtable
{
get
{
lock(syncObject)
{
if(hash == null)
{
hash = new Hashtable();
//Call sproc and use IDataReader to fill up the Hashtable
}
return hash;
}
}
}
}

I was wondering if instead of using the way I am doing now, can i do :

private static Hashtable hash = fillHashTable();

then I have a private function :

private Hashtable fillhashTable()
{
Hashtable resultHash = new Hashtable().Synchronized;
//Call the sproc and use IDataReader to fill up the Hashtable
}

and then finally in my Get i do

public static Hashtable Hash
{
get {return hash};
}


Is this a safe way of doing it??

Thanks alot again!

0
 
gregoryyoungCommented:
your static constructor is gaurenteed to e called before any other accessor ...

now does this information ever get deleted/changed?

Greg

0
 
lordianoAuthor Commented:
No, it will be consistent throughout the running cycle of the program.
There will be multiple thread accessing this Hashtable, but all of them are just reading it.
0
 
lordianoAuthor Commented:
Ops! I forgot to awarded the point.  Sorry about the delay, thanks a lot for your inputs.
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

  • 6
  • 4
  • 2
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now