I'm maintaining code for a web application built using Asp.NET MVC. An MVC dependency resolver has been implemented using Unity container. Here's the cleanup code that's called on application shutdown.
public static void Shutdown()
{
IUnityContainer container = UnityConfig.GetConfiguredContainer();
container.Dispose(); //currently when called causes stack overflow
}
The issue we're having is that during a shutdown the call to dispose (above) causes a stack overflow exception and then the process crashes because of it. This also occurs during development when debugging the app and making changes to web.config (since changes to web.config seems to restart the application) which also stops the debugging session which normally shouldn't end. No stack overflow seems to occur if I remove the call to dispose, and the application then exits or restarts normally without the process crashing during debugging sessions.
I'm thinking of simply permanently removing the call to Dispose but I'm uncertain of the consequences, wouldn't an application shut down inevitably lead to the disposing of the container anyway?
If removing the call to dispose is not recommended then the only option would be to find the real cause which I believe lie in a circular dependency within the container itself, but I can't find it, how should I debug this issue ?
The cause of the stackoverflow is infinite recursive call to Dispose of UnityContainer, which I think is (weirdly) caused by the automatically registered IUnityContainer which is not managed by our code and should be handled in unity library. I was able to stop the infinite recursion simply by swapping out the usage of the UnityContainer class with a derived class that override Dispose and returns on a recursive call:
public class CustomUnityContainer : UnityContainer
{
private bool inDispose = false;
protected override void Dispose(bool disposing)
{
if (inDispose) //prevents recursive calls into Dispose
return;
inDispose = true;
base.Dispose(disposing);
inDispose = false;
}
}
Related
I am doing stress testing for web api (webapi2) with 20 users on boarding in 0 seconds. I am getting the following errors.
System.Data.Entity.Core.EntityCommandExecutionException: An error occurred while executing the command definition. See the inner exception for details. ---> System.InvalidOperationException: Invalid operation. The connection is closed.
Another error
System.Data.Entity.Core.EntityException: The underlying provider failed on Open. ---> System.InvalidOperationException: The connection was not closed. The connection's current state is connecting.
My code to get the DBContext, each time a new DBContext is getting created:
public static ForcesChecker_Context GetDataContext()
{
return new ForcesChecker_Context();
}
For one web api request this code is getting executed multiple times and multiple instances of this object is getting created. When I call 20 users at a time, it generates 20* ~10 = ~200 objects are created.
My connection string:
Min Pool Size=1;Max Pool Size=200;
It seems there is a race condition.
What settings would help to allow more users to access my system concurrently?
I fixed it. The reason was, Connection Leak. There are other places in the application wherein the DBContext object wasn't disposed properly. Particularly in UnitOfWork class, DBContext object is used, but not disposed inside the Dispose() method. That led to the connection leak. Subsequently, that led to the race condition when new threads (http requests) try to use a connection from the connection pool. Here is the solution code.
public class UnitOfWork: IDisposable, IUnitOfWork
{
ForcesChecker_Context forcesContext; //EntityFramework DBContext
...
public void Dispose()
{
forcesContext.Dispose(); //Leak prevented by this new line.
}
...
}
Thumb rule is, always remember to use Transient Life Time for the DBContext. That is a new instance every time, and dispose them immediately after use.
One of my old question had to do with viewing pdf files in monotouch ( I managed to accomplish this). Port of the iOS pdf viewer for xamarin
My issue is as following: if I start to close and open a pdf view( view with catiledlayer) really fast and often my app crashes with a:
Got a SIGSEGV while executing native code. This usually indicates
a fatal error in the mono runtime or one of the native libraries
used by your application.
After researching around the internet for a few days I found a post saying something along the lines of: The image back store is being cleaned and this is causing the error.
Edit:
Ok, I have come to the conclusion that my app is cleaning the memory and my pointers are turning into nulls. I called Gc.Collect() a couple of times and this seems to be the root of the problem.
I have removed all my calls to GC.Collect() and I currently running a stress test and will update as I identify the issue.
After running some more tests this is what I found out:
The error seems to orignate from the TiledLayerDelegate : CALayerDelegate class.
The app only crashes if the method Dispose from CALayerDelegate is called, overriding the method as empty seems to prevent the app from crashing.
Running the app seems to cause no issue whatsoever anymore. It is apparent that something is going really wrong on the Dispose method of the CALayerDelegate.
Last finding: Running the app like a monkey tends to heat up the app a good bit. I assume this is due to the intensive rendering of pdf pages ( they are huge sheets about 4,000 X 3,000 pxs)
protected override void Dispose (bool disposing)
{
try{
view = null;
GC.Collect (2);
//base.Dispose (disposing);
}catch(Exception e) {
//System.Console.Write(e);
}
}
Now more than anything, I am just wondering if the phone heating up is really as I assume nothing more than the CPU rendering the sheets and is normal. Does anyone have any ideas as to how best deal with the Dispose override?
Last Edit: for anyone wanting to prevents crashes this is what my last version of the layer view class looks like.
public class TiledPdfView : UIView {
CATiledLayer tiledLayer;
public TiledPdfView (CGRect frame, float scale)
: base (frame)
{
tiledLayer = Layer as CATiledLayer;
tiledLayer.LevelsOfDetail = 4; //4
tiledLayer.LevelsOfDetailBias = 4;//4
tiledLayer.TileSize = new CGSize (1024, 1024);
// here we still need to implement the delegate
tiledLayer.Delegate = new TiledLayerDelegate (this);
Scale = scale;
}
public CGPDFPage Page { get; set; }
public float Scale { get; set; }
public override void Draw (CGRect rect)
{
// empty (on purpose so the delegate will draw)
}
[Export ("layerClass")]
public static Class LayerClass ()
{
// instruct that we want a CATileLayer (not the default CALayer) for the Layer property
return new Class (typeof (CATiledLayer));
}
protected override void Dispose (bool disposing)
{
Cleanup ();
base.Dispose (disposing);
}
private void Cleanup ()
{
InvokeOnMainThread (() => {
tiledLayer.Delegate = null;
this.RemoveFromSuperview ();
this.tiledLayer.RemoveFromSuperLayer ();
});
}
Apple's sample code around that is not really great. Looking at the source of your tiled view I do not see a place where you set the layer delegate to nil. Under the hood, CATiledLayer creates a queue to call the tiled rendering in the background. This can lead to races and one way to work around this is explicitly nilling the delegate. Experiments showed that this can sometimes block, so expect some performance degradation. Yes, this is a bug and you should file a feedback - I did so years ago.
I'm working on a commercial PDF SDK (and we have a pretty popular Xamarin wrapper) and we moved away from CATiledLayer years ago. It's a relatively simple solution but the nature of PDF is that to render a part, one has to traverse the whole render tree - it's not always easy to figure out what is on screen and what is not. Apple's renderer is doing an ok-ish job on that and performance is okay, but you'll get a better performance if you render into one image and then move that around/re-render as the user scrolls. (Of course, this is trickier and harder to get right with memory, especially on retina screens.)
If you don't have the time to move away from CATiledLayer, some people go with the nuclear option and also manually remove the layer from the view. See e.g. this question for more details.
I am new to StructureMap and am using it to construct an app that uses clrzmq, which is a .NET implementation of ZeroMQ.
ZeroMQ apps work by creating a single context instance and, from that instance, creating one or more ZMQ sockets to send stuff around.
In order to cleanly shut down a clrzmq app, you need to first close and Dispose any connected ZMQ sockets created from the ZMQ context, and then, only after that is done, you Dispose the ZMQ context.
If you attempt to Dispose the context prior to closing & Disposing one or more of the sockets created from that context, the Dispose call on the context will hang and your app will not exit.
So, I am looking for a way to ensure that this Dispose order is obeyed by the StructureMap containers in this app.
I've tried a registry class with wiring like so:
For< ZeroMQ.ZmqContext >().Singleton();
Profile( "SomeProfile", p =>
{
// ZmqContext instances are created with a
// custom factory method
p.For< ZeroMQ.ZmqContext >()
.Use( ZeroMQ.ZmqContext.Create() );
p.For< ISender >()
.Use< MyConcreteZmqSender >();
});
...in the above, "MyConcreteZmqSender" is a class that creates a ZMQ socket using the ZMQ context instance it receives in its constructor (the only constructor argument). It implements IDisposable, where the Dispose() implementation closes the created socket and calls Dispose() on it.
I also have a test case written to test out the Dispose behavior that looks like so:
[Test]
public void TestZmqSender()
{
ObjectFactory.Initialize( x =>
{
x.AddRegistry<MyZmqRegistry>();
} );
ObjectFactory.Profile = "SomeProfile";
ISender sender = ObjectFactory.Container.GetNestedContainer().GetInstance<ISender>();
sender.doAllTheThings();
ObjectFactory.Container.GetNestedContainer().Dispose();
ObjectFactory.Container.Dispose();
}
...in the above I tried using the nested container to get the Zmq sender instance, thinking that if I retrieve it that way, then if I later call Dispose on the nested cotainer, it will call Dispose on my socket sender before the ZMQ context gets disposed, which I assumed would happen when I called Dispose on the main parent container.
Alas, this does not appear to be what is happening, and this test case never completes. I have verified that the sender is getting properly constructed with a reference to the singleton ZMQ context. And, of course, if I manually call sender.Dispose() prior to disposing the main container, the test case completes successfully.
My first attempt didn't use the nested container at all, and it also hangs in the same way.
Anybody have any recommendations for how I can get this done without having to get a handle to all the sender instances and manually calling Dispose() on them and ensure that this is done prior to calling Dispose() on the main container?
Id'like to develop a web services + web sockets server using dart but the problem is I can't ensure the server's high availability because of uncatched exceptions in isolates.
Of course, I have try-catched my main function, but this is not enough.
If an exception occurs in the then() part of a future, the server will crash.
Which means that ONE flawd request can put the server down.
I realize that this is an open issue but is there any way to acknoledge any crash WITHOUT crashing the VM so that the server can continue serving other requests ?
Thank you.
What I've done in the past is use the main isolate to launch a child isolate which hosts the actual web server. When you launch an isolate, you can pass in an "uncaught exception" handler to the child isolate (I also think you should be able to register one at the top-level as well, to prevent this particular issue, as referenced by the issue in the original question).
Example:
import 'dart:isolate';
void main() {
// Spawn a child isolate
spawnFunction(isolateMain, uncaughtExceptionHandler);
}
void isolateMain() {
// this is the "real" entry point of your app
// setup http servers and listen etc...
}
bool uncaughtExceptionHandler(ex) {
// TODO: add logging!
// respawn a new child isolate.
spawnFunction(isolateMain, uncaughtException);
return true; // we've handled the uncaught exception
}
Chris Buckett gave you a good way to restart your server when it fails. However, you still don't want your server to go down.
The try-catch only works for synchronous code.
doSomething() {
try {
someSynchronousFunc();
someAsyncFunc().then(() => print('foo'));
} catch (e) {
// ...
}
}
When your async method completes or fails, it happens "long" after the program is done with the doSomething method.
When you write asynchronous code, it's generally a good idea to start a method by returning a future:
Future doSomething() {
return new Future(() {
// your code here.
var a = b + 5; // throws and is caught.
return someAsyncCall(); // Errors are forwarded if you return the Future directly.
});
}
This ensures that if you have code that throws, it catches them and the caller can then catchError() them.
If you write this way, you have much less crashes, assuming that you have some error handling at the top level at least.
Whenever you are calling a method that returns a Future, either return it directly (like shown above) or catchError() for it so that you are handling the possible errors locally.
There's a great lengthy article on the homepage that you should read.
Most of my UIKit Dispose overrides do something with other views before they get destroyed:
protected override void Dispose (bool disposing)
{
if (ScrollView != null) {
ScrollView.RemoveObserver (this, new NSString ("contentOffset"));
ScrollView.RemoveObserver (this, new NSString ("contentInset"));
ScrollView = null;
}
base.Dispose (disposing);
}
I just recently realized that Dispose will run on finalizer thread if disposing is false.
In this case ScrollView.RemoveObserver will be called from non-UI thread which is Bad.
What's the safe way to do UIKit-related cleanup in Dispose?
If disposing is false, then you would probably be better off not calling that code.
protected override void Dispose (bool disposing)
{
if (disposing)
{
if (ScrollView != null) {
ScrollView.RemoveObserver (this, new NSString ("contentOffset"));
ScrollView.RemoveObserver (this, new NSString ("contentInset"));
ScrollView = null;
}
}
base.Dispose (disposing);
}
As a more general answer to your question - assuming this code is in a UIViewController - it might be better to attach/detach these observers inside ViewDidAppear, ViewDidDisappear - then you can avoid this issue altogether.
Adam Kemp posted a great explanation in a mirror thread on Xamarin forums.
Only if disposing is true should you do any of that work. If it's
false then you're being called from a finalizer and so it's not safe
to access that other object. The only things you should access in that
case would be any unmanaged resources (like an IntPtr which stores a
native allocation you need to free or a native thread you need to
kill).
This obviously brings up the question of when to do the work you're
currently doing there. If you're in a view controller then you could
use a method like WillDisappear. If you are in a view then you could
just use WillMoveToWindow (which gets called with null as the window
if you are being removed from the window).
Another important bit regarding ReleaseDesignerOutlets:
You can't call ReleaseDesignerOutlets when called from a finalizer
either. Remember, it is not safe to look at any other managed objects
referenced by your object in your finalizer. Those objects may no
longer exist.
This is safe to skip because each of those other objects already has a
similar finalizer. If you never get around to calling Dispose() on
them then they will have their finalizers called from the finalizer
thread, and in that case their own finalizer will call their own
Dispose(bool) with a false, which means "you're being called from a
finalizer". Since the native object is an unmanaged resource (just an
IntPtr) it is safe for their Dispose(bool) method to release the
reference to those native resources to allow those native objects to
leave memory.
You can actually use the assembly browser to look at what NSObject's
Finalize and Dispose(bool) methods do to verify what I just described.
Whatever you do, never access your managed resources from within a
finalizer, which means never access them from Dispose(bool) when the
disposing argument is false.
Thanks Adam!
Could you use
InvokeOnMainThread(delegate {....})
to kill the UIKit stuff? Not 100% sure it'd do what you want, but thats the normal way of doing UIKit stuff when you might be on / are on a different thread.