0

Scenario (note this is hand written dummy code - might not work :)

public class MySuperClass
{
    private static Dictionary<int, MySuperClass> _instances = new Dictionary<int, MySuperClass>

    private SPWeb _contextWeb;
    private MySuperClass(SPWeb web)
    {
        // construct me
        _contextWeb = web;
    }

    public static GetSuperClass(int id)
    {
       if (_instances.ContainsKey(id))
       {
           return _instances[id];
       }

       var instance = new MySuperClass(SPContext.Current.Web);
       _instances.Add(22, instance);
    }
}

public class SampleApplication
{
    int _id = 22;
    public void Run()
    {
        // get MySuperClass
        var msc = MySuperClass.GetMySuperClass(22);
        msc.SomeOperationOnItsContextWeb(); // like reading from the PropertyBag..
    }
}

The sum of MySuperClass instances (inside the static field) will be limited (as in "not indefinite"). Once an instance is put there for a certain "id" it will be reused over and over. The question is... if I run any operations from within my MySuperClass on my _contextWeb - will they at some point fail?

I would prefer to have this specific SPWeb in memory because I don't want to create a new SPWeb instance all the time (= every request). That's why the whole MySuperClass is stored in a static field anyway. We are talking about a Web Publishing Scenario with 500 concurrent users (easily). So that would be expensive.

I am also totally aware that any contextWeb would not ever been garbage collected right now. But since I'm in control of all my MySuperClass instances I could call Dispose() on them (not implementing IDisposable in the example above).

lapsus
  • 467
  • 1
  • 7
  • 14

2 Answers2

1

If you are retrieving the SPWeb from the SPContext.Current then you should NOT dispose it. However, if you are instantiating it yourself (i.e. SPSite.OpenWeb(), etc.) then you SHOULD dispose of it.

John Chapman
  • 11,941
  • 6
  • 36
  • 62
  • That's a very vague answer. I am of course adding a SPWeb from SPContext.Current. Either Web or Parent or Parent.Parent [...]. However I'm storing this web longer than than one HttpRequest. In fact I want to store it for the entire application lifetime. I explicitely do not want to dispose it. This is not a SPWeb disposal question. – lapsus Nov 22 '13 at 16:01
  • You should not be keeping the SPWeb open longer than necessary. Each request should use a new SPWeb (or get it from the SPContext). – John Chapman Nov 22 '13 at 18:41
0

Any object created by the context is not guaranteed to live longer than the context, even if you hold onto a reference to it. If you must control the lifetime of your object then create your own reference to it by creating new SPSite and SPWeb objects based on the URLs in the original context. Store both of these objects for as long as your app needs them.

Also, make sure that your class implements the IDisposable interface so that it participates properly in garbage collection and that it explicitly calls the .Dispose() method on both of the SPWeb and SPSite objects that you created and stored earlier.

However, generally speaking, if your app functions properly using the current context web then it really makes more sense to use that when processing requests rather than store a single SPWeb off for later repeated use. If your code could possibly be called by two different SPWebs on the same farm, then storing an SPWeb off for later will break outright.

Dave Wise
  • 13,181
  • 18
  • 19
  • I agree on creating (and disposing) SPWeb objects myself rather than using ones from a HttpContext long time ago. To clarify the use case - I cannot use SPContext.Current.Web because I often need to refer from different webs to a particular one. But I admit I wonder if its any good to keep a whole SPWeb in memory if you just want to frequently access the propertybag for example. – lapsus Nov 22 '13 at 17:37
  • If all you need is the propertybag and even then you only need to read it then it would make more sense to store that information in a collection rather than store the entire SPweb and SPSite objects. If you are changing the values in the propertybag then you are back fighting the same issue - holding on to a reference to unmanaged objects. – Dave Wise Nov 22 '13 at 17:49