Where is my Object being disposed? - c#

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)

Check if this helps:
Add a new breakpoint using Debug > New Breakpoint > Break at Function... (Ctrl+B).
Enter Microsoft.SharePoint.SPWeb.Dispose in the Function edit box.
Dismiss the dialog box that says that Intellisense could not find the specified location.
Run under the debugger.
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.

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.

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()

Related

ASP.NET Find out which Response.Redirect is redirecting?

I have a huge website with a huge backend. Somewhere, somehow, there is a Response.Redirect called while trying to open a site (debug environment).
Is there a way to find out, which Response.Redirect causes the redirect?
An certain way would be to set a debug breakpoint on every Response.Redirect in the whole website. But this is a lot of effort.
Another idea I had was to stop at the "ThreadAbortException" (which is thrown by Response.Redirect) with "Debug->Exceptions..". But this doesn't work. Seems like the frame or whatever is no longer executed to get a break on it.
Last attempt was to watch the call-stack. But the stack never gets to the last Response.Redirect because it is a new frame call.
Well, I got an idea which solved my problem but required massive code replacement (which is not a problem with 'Find and replace').
I created an static class:
public static class OwnResponse
{
public static void Redirect(string Url, bool EndResponse = true)
{
HttpContext.Current.Response.Redirect(Url, EndResponse); // set the breakpoint here
}
}
Then I replaced every Response.Redirect in the code with OwnResponse.Redirect. Now I was able to set my breakpoint onto the first line in the class. I called the website and the breakpoint got hit. Then I just watched the call-stack and knew where the redirect occurs.
There is another possible solution, which requires a bit more work. You have to get "Stepping into .NET code" to run. Then you can easily set a break point in the .NET method's first line.
Open the Exception Settings window and search for "threadabort". Check the checkbox for the ThreadAbortException. Now, when a redirect is executed from code, your debug session will enter break mode.
You can use below code in landing page:-
string yourPreviousUrl = Request.UrlReferrer.ToString();
if(!string.IsNullOrEmpty(yourPreviousUrl))
{
//Referrer was found!
}
else
{
//Unable to detect a Referrer
}
As mention in official site :-
HttpRequest.UrlReferrer Property
Gets information about the URL of the client's previous request that
linked to the current URL.
You could try to implement tracing and save the results to a file. The trace data might help you to pinpoint your redirect.
Here is a link with some more background on ASP.NET tracing:
http://www.codeproject.com/Articles/82290/Step-by-Step-Guide-to-Trace-the-ASP-NET-Applicatio
Use fiddler or another http traffic capture tool and capture the network traffic. You should be able to see the request that was initiated and take it from there.

Windows Form Won't Display in Debug Mode

I recently upgraded to VS 2012. I have a set of coded UI tests that I've coded in VS 2010 and I'm trying to spin them up in VS 2012. I have a windows form that I'm displaying at the beginning of the test run by using the AssemblyInitialize attribute. I use this form to allow users to select from sets of values and those values are used to data feed the tests. Here's a copy of my code that displays the form:
[AssemblyInitialize]
public static void AssemblyInitialize(TestContext context)
{
ProcessUtility.TerminateAll();
if (!File.Exists(Directory.GetCurrentDirectory() + #"\RunInfo.ser"))
{
InitializeForm initForm = new InitializeForm();
initForm.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
initForm.ShowDialog();
}
}
So, here's my headache: the form displays just fine in Run mode. However, if I try to spin it up in Debug mode, it never displays. I've stepped through the code. It's loading all of the controls for the form with no errors. I make it to the 'initForm.ShowDialog()' line of code. It runs that line of code but then nothing happens. I don't receive any errors and the status in the lower left of the IDE is 'Ready'. It's almost as if the IDE thinks the form is displayed but it's not. I've double-checked the Task Manager and it's just not there. I've verified the build configuration is set to Debug. I've tried cleaning the solution and re-building. This code continues to work in VS 2010. Please tell me someone out there has ran into a similar problem because I'm out of ideas. I'm new to stackoverflow so let me know if there is anything else I can provide to better explain the issue. Thank you in advance for taking a look at it.
Not sure why this solution works, but I was able to solve this issue in VS2013 by setting the visible property on the form I was trying to display to true and then false before calling ShowDialog.
VB.Net example code
Dim form as Form = new Form
form.Visible = True
form.Visible = False
form.ShowDialog
I was able to get the form to display using the following code instead of ShowDialog. I still have no idea why ShowDialog wasn't working but this does the trick:
InitializeForm initForm = new InitializeForm();
initForm.Visible = true;
initForm.Focus();
Application.Run(initForm);
Most likely a exception is happening during the initialization, Go in to the Debug->Exceptions dropdown menu and be sure the checkbox thrown for Common Language Runtime Exceptions is checked, this will let your code break on the exception that is happening.
If you are still not catching the exception go to Debug->Option and Settings then uncheck the box for Enable Just My Code and check the box for Break when exceptions cross AppDomain or managed/native boundries
This may give you some "read herring" exceptions, as some .NET processes use exceptions for control of flow logic. So just be aware that the first exception you see may not be the cause of your problem.
I was experiencing the same thing while debugging an old code and resolved the situation by adding [STAThread] attribute on top of container method which contains form.ShowDialog();
For example:
[STAThread]
public void MessageBoxShow(string errorMessage)
{
using (frmError errorForm = new frmError(errorMessage))
{
errorForm.ShowDialog();
}
}
This has solved any hanging occured while hitting-continuing debug point.
Platform Windows 7 x64 enterprise edition and VS2008 (both has latest updates as of today).
Hope this helps.
Update 1: Please ignore using statement in example since I am using a custom form which inherits IDisposable in addition to Windows.Form and has custom disposition routines. Sorry if it has created any confusion.

"The debugger cannot continue running the process."

I've been messing with VS 2010 debugging settings, trying to get stepping into the .NET Framework working. Well, I can't get it to work. I've also tried the Reflector VS plugin and that was working at one point.
Then I randomly started getting this error:
This only happens when I have a breakpoint on a line that calls IEnumerable<T>.ToList(). If I try to step-over or step-into on that line where my breakpoint is set, I get this error dialog and my debugging session ends.
If I move the breakpoint to the line below, the debugger makes it past the ToList() call!
I've tried the following to no avail:
Removing the Reflector plugin.
Undoing my changes in the Tools > Options > Debugging window (unchecked the option to step into the .NET Framework; unchecked the source server option; checked the just my code option).
Unchecked Microsoft Source Server in the Tools > Options > Debugging > Symbols window.
Cleared the symbol cache.
What is going on?
Because this was the first place I came to when I searched for an answer, I'll add what I found out.
In my case, I had the debugger set up in the solution to start multiple projects. For some reason this setting was changed by Visual Studio so that no project was starting. Correcting the setting in the solution immediately solved the problem.
The problem was not difficult to solve, but the error message was more than a bit irritating.
I've just found this answer useful. All I did was change my start-up project to another, and back to normal.
My project probably lost this setting somewhere, and resetting it made it available again.
It was a ToString() override that make the debugger crash ! (After the evaluation the debugger will show you the result with the ToString() method). And if you get an exception in the ToString(), you will never catch an exception because you cannot code them on the debugger behaviour.
I've got this answer from msdn
I suffered from same problem....
I found one solution which heard uncommon....
The debugger cannot continue running the process.Process was terminated
While debugging your code step by step , you will find the line , from where error redirecting.
If you are using " ToString() " anywhere in that file ,please remove that .
Instead of the ,you can use Value / Text .
It works fine.
............
If you were not used ToString() any where in program , then reload project copy by removing completely.
I had the same problem. I traced it down to a class(step-by-step debugging) and finally to a property(commenting all the code, then step-by-step uncommenting).
this property returned a typed dataSet from a table.Dataset
private typedDataSet myDataSet
{
return this.DataSet as typedDataSet;
}
this was in a DataTable partial class.
After I removed this property everything went OK.
I ran into this issue with a code bug from copy/paste. Instead of get/setting the private member variable, I did a get/set on itself. When I referenced the property in other code the debugger terminated (2010):
public bool ProdToDeve
{
get { return ProdToDeve; } // <= missing underbar
set { ProdToDeve = value; }
}
private bool _ProdToDeve = false;
This message will also show up when you're trying to debug a Xamarin solution but you have a class library selected as the startup project instead of your application porject.
It occurred to me when I was doing the following:
throw new Exception(timeout.TotalSeconds + " second(s)");
That's because timeout.TotalSeconds.ToString() which indeed is an override method for an object of type double, was throwing a Parameter not valid exception.
Finally, for safety I ended up doing the following:
throw new Exception(System.Convert.ToString(timeout.TotalSeconds));
Well, typically, this is also the kind of error message you can get in a multi-threads context. In brief, it involves concurrency : make sure that your resource accesses are always secured.
In my case, I got this error message when I forgot to secure resource accesses at some places within my code. To solve this issue, I just had to decorate the critical sections with a lock instruction (on the concerned resource). I hope this will help those who are in this context.

Completed Event not triggering for web service on some systems

This is rather weird issue that I am facing with by WCF/Silverlight application. I am using a WCF to get data from a database for my Silverlight application and the completed event is not triggering for method in WCF on some systems. I have checked the called method executes properly has returns the values. I have checked via Fiddler and it clearly shows that response has the returned values as well. However the completed event is not getting triggered. Moreover in few of the systems, everything is fine and I am able to process the returned value in the completed method.
Any thoughts or suggestions would be greatly appreciated. I have tried searching around the web but without any luck :(
Following is the code.. Calling the method..
void RFCDeploy_Loaded(object sender, RoutedEventArgs e)
{
btnSelectFile.IsEnabled = true;
btnUploadFile.IsEnabled = false;
btnSelectFile.Click += new RoutedEventHandler(btnSelectFile_Click);
btnUploadFile.Click += new RoutedEventHandler(btnUploadFile_Click);
RFCChangeDataGrid.KeyDown += new KeyEventHandler(RFCChangeDataGrid_KeyDown);
btnAddRFCManually.Click += new RoutedEventHandler(btnAddRFCManually_Click);
ServiceReference1.DataService1Client ws = new BEVDashBoard.ServiceReference1.DataService1Client();
ws.GetRFCChangeCompleted += new EventHandler<BEVDashBoard.ServiceReference1.GetRFCChangeCompletedEventArgs>(ws_GetRFCChangeCompleted);
ws.GetRFCChangeAsync();
this.BusyIndicator1.IsBusy = true;
}
Completed Event....
void ws_GetRFCChangeCompleted(object sender, BEVDashBoard.ServiceReference1.GetRFCChangeCompletedEventArgs e)
{
PagedCollectionView view = new PagedCollectionView(e.Result);
view.GroupDescriptions.Add(new PropertyGroupDescription("RFC"));
RFCChangeDataGrid.ItemsSource = view;
foreach (CollectionViewGroup group in view.Groups)
{
RFCChangeDataGrid.CollapseRowGroup(group, true);
}
this.BusyIndicator1.IsBusy = false;
}
Please note that this WCF has lots of other method as well and all of them are working fine.... I have problem with only this method...
Thanks...
As others have noted, a look at some of your code would help. But some things to check:
(1) Turn off "Enable Just My Code" under Debug/Options/Debugging/General, and set some breakpoints in the Reference.cs file, to see whether any of the low-level callback methods there are getting hit.
(2) Confirm that you're setting the completed event handlers, and on the right instance of the proxy client. If you're setting the event handlers on one instance, and making the call on another, that could result in the behavior you're describing.
(3) Poke around with MS Service Trace Viewer, as described here, and see if there are any obvious errors (usually helpfully highlighted in red).
Likely there are other things you could check, but this will keep you busy for a day or so :-).
(Edits made after code posted)
(4) You might want to try defining your ws variable at the class level rather than the function. In theory, having an event-handler defined on it means that it won't get garbage collected, but it's still a little odd, in that once you're out of the function, you don't have a handle to it anymore, and hence can't do important things like, say, closing it.
(5) If you haven't already, try rebuilding your proxy class through the Add Service Reference dialog box in Visual Studio. I've seen the occasional odd problem pop up when the web service has changed subtly and the client wasn't updated to reflect the changes: some methods will get called successfully, others won't.
(6) If you're likely to have multiple instances of a proxy client open at the same time, consider merging them into one instance (and use the optional "object userState" parameter of the method call to pass the callback, so you don't run into the nasty possibility of multiple event handlers getting assigned). I've run into nasty problems in the past when multiple instances were stepping on each other, and my current best practice is to structure my code in such a way that there's only ever one client instance open at a time. I know that's not necessarily what MS says, but it's been my experience.
This issue is because of special characters in one of the fields returned from DB which browser was not able to render. After considerable debug n search over the web, was able to find this out. Used Regular expressions to remove these special characters in WCF, the new returned values from the method was successfully rendered in various browsers on different system. :)
Make sure you have checked 'Generate asynchronous operations' in your service reference. Right-click on the service reference and check the box. This solved it for me.

solution for RPC_E_ATTEMPTED_MULTITHREAD error caused by SPRequestContext caching SPSites?

I'm developing a solution for SharePoint 2007, and I'm using SPSecurity.RunWithElevatedPrivileges a lot, passing in UserToken of the SystemAccount.
After reading http://hristopavlov.wordpress.com/2009/01/19/understanding-sharepoint-sprequest/ I finally began to understand why I get these System.Runtime.InteropServices.COMException (0x80010102): Attempted to make calls on more than one thread in single threaded mode. (Exception from HRESULT: 0x80010102 (RPC_E_ATTEMPTED_MULTITHREAD)) errors, but there seems to be no solution - "known issue in the product"
The article is more then a year old. I wasn't able to find anything more recent and helpful, but I was hoping maybe someone else has?
My code goes like this
SPSecurity.RunWithElevatedPrivileges(delegate()
{
using (SPSite elevatedSite = new SPSite(web.Site.ID, web.Site.SystemAccount.UserToken))
{
using (SPWeb elevatedWeb = elevatedSite.OpenWeb(web.ID))
{
// some operations on lists and items obtained through elevatedWeb
}
}
}
The errors come up wherever such an elevated code is used, and more often when there are more users who use these functionalities, so I guess perhaps the elevated SPSite is getting cached and reused.
Is there any way to solve this? If my understanding is correct, how to make Sharepoint forget about the cached SPSites, and use a fresh one instead?
Thanks
Solved it myself, after finally understanding what I'm actually doing there - by using for example new SPSite(web.Site.ID, I'm actually making the delegate, which seems to be on a new thread, reach into web, which is on the original thread
So the answer is: you have put all the data you'll need (like various IDs, SystemAccount.UserToken etc.) into variables before running the delegate, and don't access any objects with associated SPRequest (webs, lists, items, users...) from inside the delegate. And, of course, the same holds for data that goes out of the delegate - you can return web ID, list ID and item ID, but you better not return SPListItem.

Categories

Resources