Murphy, James [mailto:[EMAIL PROTECTED]] wrote:

> If you
> let the GC handle it you cache my grow larger than you'd dare
> let it if you managed it yourself.

So you're saying you think you can write better a memory manager than the
GC? =)

Seriously though, this is exactly what weak references are made for. Take
advantage of what the platform offeres you first and do some performance
testing before writing all sorts of custom code that may not even yield a
big enough gain to have warranted it, or even worse... perform more poorly!

I have a design in my head that is basically a dictionary which takes a key,
probably a string, and a value which is a delgate of the following
signature:

<codeSnippet language="C#">
public delegate DataSet DataSetBuilder();
</codeSnippet>

Then, you add the delegates to the dictionary and your have a special method
called something like GetDataSet which is implemented like so:

<codeSnippet language="C#">
public class CachedDataSetDictionary : DictionaryBase
{
  IDictionary cachedDataSetsDictionary;

  public CachedDataSetDictionary()
  {
    this.cachedDataSetsDictionary = new Hashtable();
  }

  public void Add(string key, DataSetBuilder builder)
  {
    ((IDictionary)this).Add(key, builder);
  }

  public DataSet GetDataSet(string key)
  {
    // Get the weak ref from internal cache dictionary
    WeakReference cachedDataSetReference =
(WeakReference)this.cachedDataSetsDictionary[key];
    DataSet result;

    Trace.WriteLine(String.Format("Looking for \"{0}\" cached DataSet...",
key));

    // Check if the weak ref for the specified key existed yet, if not
create now
    if(cachedDataSetReference == null)
    {
      Trace.WriteLine("DataSet has never been cached, building for the first
time.");

      result = BuildDataSet(key);

      cachedDataSetReference = new WeakReference(result);

      this.cachedDataSetsDictionary.Add(key, cachedDataSetReference);
    }
    else
    {
      // Check if weak ref's target is still alive, if not rebuild now
      if(!cachedDataSetReference.IsAlive)
      {
        Trace.WriteLine("Cache miss!!! DataSet was GCd, need to rebuild.");

        result = BuildDataSet(key);
        cachedDataSetReference.Target = result;
      }
      else
      {
        // DataSet hasn't been GCd yet, cache hit!!
        Trace.WriteLine("Cache hit!!!");

        result = (DataSet)cachedDataSetReference.Target;
      }
    }

    return result;
  }

  private DataSet BuildDataSet(string key)
  {
    // Get the delegate from DictionaryBase
    DataSetBuilder builderDelegate =
(DataSetBuilder)((IDictionary)this)[key];

    // Invoke it and return resulting DataSet
    return builderDelegate();
  }
}
</codeSnippet>

HTH,
Drew
.NET MVP

You can read messages from the Advanced DOTNET archive, unsubscribe from Advanced 
DOTNET, or
subscribe to other DevelopMentor lists at http://discuss.develop.com.

Reply via email to