views:

584

answers:

3

I have a strange issue: I am using SPContext.Current.Web in a .aspx page, but at the end, I get a "Trying to use an SPWeb object that has been closed or disposed and is no longer valid." error message.

From what I see, SPContext.Current.Web is Disposed by someone, but I have no idea where. I just wonder: With Visual Studio 2005's Debugger, can I somehow see where/who disposed an Object? As I neither create nor have the source code, setting breakpoints is a problem.

What would be a good approach for finding out who disposes a given object where, without just randomly commenting out lines?

(Note: The Issue has been resolve, but the question itself also applies outside of Sharepoint)

+3  A: 

Check if this helps:

  1. Add a new breakpoint using Debug > New Breakpoint > Break at Function... (Ctrl+B).
  2. Enter Microsoft.SharePoint.SPWeb.Dispose in the Function edit box.
  3. Dismiss the dialog box that says that Intellisense could not find the specified location.
  4. Run under the debugger.
  5. When the breakpoint is hit you can see on the call stack who called the Dispose method. Hopefully for some of the times the breakpoint is hit one stack frame is in your source code.

If a dialog appears saying that There is no source code available for the current location when the breakpoint is hit dismiss it.


Note: Because I do not have SharePoint installed I have tested this with System.IO.StreamReader.Dispose but I am guessing that this should also work for SPContext.Current.Web. Drop a note on this.

smink
I'll check ASAP, but that looks like something that could work.
Michael Stum
Ok, tested it. It does kind of work, but I just noticed that there are a LOT of SPWeb/SPSite.Disposes going on normally (Breakpoint was hit at least 10 times), but that does not change the fact that it works. Marking as accepted.
Michael Stum
A: 

You should read this: http://msdn.microsoft.com/en-us/library/aa973248.aspx

To be quick: you should dispose all your SPWeb and SPSite using either

using(SPWeb web = ...)
{
    ....
}

or

SPWeb web = ...
...
web.Dispose()
Nico
You should ONLY dispose SPWeb/SPSite that you actually create. SPContext.Current.Web/Site must *not* be disposed, otherwise bad stuff happens, aka a Yellow Screen of Death as soon as Sharepoint tries to use it's SPWeb again. That's what happened to me and that was the point of my question.
Michael Stum
A: 

In your custom code make sure you didn't get a reference to the actual SPWeb object of the Context object and dispose of it. For example, the following is very bad.

using (SPWeb myWeb = SPContext.Current.Web)
{
   // do something
}

This will cause the SPContext's object to be disposed and may not cause an issue in your code, but will likely cause issues later.

Corey Roth
I know. The issue here was that the Web was passed around between 5 classes, and somewhere in between there was a Dispose() that was really deeply nested and hard to find, so I did not know if it was in my code or not, hence the need for a general breakpoint on dispose() to get the call stack
Michael Stum