Some objects created with PerWebRequest are not garbage collected at the end of web request.

96 views
Skip to first unread message

mbergal

unread,
Mar 3, 2010, 4:21:11 PM3/3/10
to Castle Project Users
Given

public class a : IDisposable
{
public static int counter;

public a()
{
counter++;
}

~a()
{
counter--;
}

public void Dispose()
{
}
}


With registration:

application_container = new WindsorContainer( );
application_container.Register( Component.For<a>( ).ImplementedBy<a>( ).LifeStyle.PerWebRequest );

Proper stuff in web.config:

<add name="PerRequestLifestyle"
type="Castle.MicroKernel.Lifestyle.PerWebRequestLifestyleModule,
Castle.MicroKernel"/>

Using version of Castle built from SVN.
With web page code:

public partial class _Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
GC.Collect( 2 );
var a = Global.application_container.Resolve<Global.a>();
Response.Write( Global.a.counter.ToString() );
}
}

I get that ~a() is not called and RedGate profiles shows that a is not
being collected, the reference to it stuck in
AllComponentsReleasePolicy.instance2burden.


mbergal

unread,
Mar 4, 2010, 2:22:55 AM3/4/10
to Castle Project Users
Hey guys,

Please help me out here. Should I post to castle-devel? Am I asking
something totally stupid?

John Simons

unread,
Mar 4, 2010, 3:54:47 AM3/4/10
to Castle Project Users
Not sure if this makes any difference but you registration could
should be:
application_container.Register( Component.For<a>( ).LifeStyle.PerWebRequest );

Cheers
John

Jason Meckley

unread,
Mar 4, 2010, 10:20:34 AM3/4/10
to Castle Project Users
Windsor has a concept of a Burden. A Burden is anything that will
impact the creation/destruction of the object. A common Burden is the
DisposableBurden which will dispose of the component when it's
released. Gobal.a implements IDisposable so it gets this Burden. This
burden will not be removed until the object is released.

Because you explicitly resolve the component in the page load event,
you will also need to explicitly release the component as well.
Global.a instance;
try
{
instance = application_container.Resolve<Global.a>();
label.Text = instance.counter.ToString();
}
finally
{
if(instance != null)
{
application_container.Release(instance);

achern...@gmail.com

unread,
Mar 4, 2010, 12:42:32 PM3/4/10
to Castle Project Users
Does it mean that if I Resolve any component from the container I
should Release it also?

On Mar 4, 9:20 am, Jason Meckley <jasonmeck...@gmail.com> wrote:
> Windsor has a concept of a Burden. A Burden is anything that will
> impact the creation/destruction of the object. A common Burden is the
> DisposableBurden which will dispose of the component when it's
> released. Gobal.a implements IDisposable so it gets this Burden. This
> burden will not be removed until the object is released.
>
> Because you explicitly resolve the component in the page load event,
> you will also need to explicitly release the component as well.
> Global.a instance;
> try
> {
>    instance  = application_container.Resolve<Global.a>();
>    label.Text = instance.counter.ToString();}
>
> finally
> {
>     if(instance != null)
>     {
>         application_container.Release(instance);
>     }
>
> }
>

Cheers,
AC

Jason Meckley

unread,
Mar 4, 2010, 5:05:52 PM3/4/10
to Castle Project Users
yes, you should. With MVC frameworks this is all done for you. With
Webforms it gets tedious.
I believe there is also a way to tell Windsor not to track components,
but I haven't used that. I try to stick with the Castle defaults as
much as possible.
I'm not sure if it still exists, but Ayende created Rhino.Igloo as
part of Rhino.Tools. It was available from SVN, I don't think he
ported it to Git though. In any case this was a framework to auto-
inject presenters into the code behind of webforms.

On Mar 4, 12:42 pm, "bspr7r...@sneakemail.com"

mbergal

unread,
Mar 4, 2010, 7:32:22 PM3/4/10
to Castle Project Users
Thanks a lot, this was a good explanation. unfortunately it still
cannot explain the following:

public class a : IDisposable
{
public static int counter;

public static int not_disposed_counter;

public a()
{
counter++;
not_disposed_counter++;
}

~a()
{
counter--;
}

public void Dispose()
{
not_disposed_counter--;
}
}

with every request counter grows, but not_disposed_counter stays the
same.

So Castle knows enough to dispose objects (basically making them
unusable), but still keeps references to them? I just cannot grok it.
Why does it need to do it? What about a principle of least surprise?
Please help.

John Simons

unread,
Mar 4, 2010, 8:24:42 PM3/4/10
to castle-pro...@googlegroups.com
Maybe you should look at your implementation of the Disposable pattern!

Run the folowing test without using Windsor:

        [Test]
        public void Test_Disposable_Pattern()
        {
            var myComponent = new a();
            Assert.AreEqual(1, a.counter);
            myComponent.Dispose();
            GC.Collect();
            Assert.AreEqual(0, a.counter);
        }

This fails!

See http://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx

Cheers
John


From: mbergal <misha....@gmail.com>
To: Castle Project Users <castle-pro...@googlegroups.com>
Sent: Fri, 5 March, 2010 11:32:22 AM
Subject: Re: Some objects created with PerWebRequest are not garbage collected at the end of web request.
--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-users+unsub...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/castle-project-users?hl=en.


 

Christian Wuerdig

unread,
Mar 4, 2010, 8:52:11 PM3/4/10
to castle-pro...@googlegroups.com
If course this fails. It would be a bug in the .Net framework if this test would succeed (because you are still holding a reference to the object). The OP complains that Castle calls Dispose but the finalizer is not called meaning it doesn't get GCed and therefor something must be holding a reference to the object. If he would have implemented the dispose pattern according to MS recommendation the finalizer would not have been called (so in order to proof his point he needed to violate that recommendation).
The answer to the OPs question was already given I believe:


Because you explicitly resolve the component in the page load event,
you will also need to explicitly release the component as well.

Means: If you explicitly call Resolve<>  on the container to get an object you need to explicitly call Release<> for that object

Cheers
Christian
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.

John Simons

unread,
Mar 4, 2010, 9:09:30 PM3/4/10
to castle-pro...@googlegroups.com
Well, so why does this test also fails?

        [Test]
        public void Test()
        {
            using (var container = new WindsorContainer())
            {
                container.Kernel.ReleasePolicy = new NoTrackingReleasePolicy();
                container.Register(Component.For<a>().LifeStyle.Transient);

                var b = container.Resolve<a>();
                Assert.AreEqual(1, a.counter);
                container.Release(b);
                GC.Collect();
                Assert.AreEqual(0, a.counter);
                var d = container.Resolve<a>();
                Assert.AreEqual(1, a.counter);
                container.Release(d);
                GC.Collect();
                Assert.AreEqual(0, a.counter);
            }
        }

And I even set the release policy to NoTrackingReleasePolicy().

Cheers
John



From: Christian Wuerdig <chri...@gmx.de>
To: castle-pro...@googlegroups.com
Sent: Fri, 5 March, 2010 12:52:11 PM

Christian Wuerdig

unread,
Mar 4, 2010, 10:02:13 PM3/4/10
to castle-pro...@googlegroups.com
Your test is flawed ;)
Leaving the Windsor stuff aside the following test usually fails (at least on my system):
           
            var b = new a();
            Assert.AreEqual(1, a.counter);
            GC.Collect();
            Assert.AreEqual(0, a.counter);

While this succeeds:

            var b = new a();
            Assert.AreEqual(1, a.counter);
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Assert.AreEqual(0, a.counter);

The reason being that calling collect doesn't mean that the finalizer queue has been processed.
Now if Windsor is behaving as claimed in an earlier email (I don't know the code and behaviour well enough to confirm that) adding GC.WaitForPendingFinalizers() to your test should make it pass.

John Simons

unread,
Mar 4, 2010, 10:18:59 PM3/4/10
to castle-pro...@googlegroups.com
Thanks Christian :)

I actually also had to set the instance variable to null for the test to pass:


        [Test]
        public void Test_Disposable_Pattern()
        {
            var myComponent = new a();
            Assert.AreEqual(1, a.counter);
            myComponent.Dispose();
            myComponent = null; //Important!
            GC.Collect();
            GC.WaitForPendingFinalizers();
            Assert.AreEqual(0, a.counter);
        }

Cheers
John

From: Christian Wuerdig <chri...@gmx.de>
To: castle-pro...@googlegroups.com
Sent: Fri, 5 March, 2010 2:02:13 PM

mbergal

unread,
Mar 4, 2010, 10:22:10 PM3/4/10
to Castle Project Users

On Mar 4, 7:52 pm, Christian Wuerdig <chris....@gmx.de> wrote:
> If course this fails. It would be a bug in the .Net framework if this
> test would succeed (because you are still holding a reference to the
> object). The OP complains that Castle calls Dispose but the finalizer is
> not called meaning it doesn't get GCed and therefor something must be
> holding a reference to the object. If he would have implemented the
> dispose pattern according to MS recommendation the finalizer would not
> have been called (so in order to proof his point he needed to violate
> that recommendation).

Thanks for answering that for me.

> The answer to the OPs question was already given I believe:
>
> Because you explicitly resolve the component in the page load event,
> you will also need to explicitly release the component as well.
>
> Means: If you explicitly call Resolve<>  on the container to get an
> object you need to explicitly call Release<> for that object

Right, but my question is rather this:

If Castle is smart enough (knows enough) to Dispose object, why isn't
it smart enough to release it? I do understand that I need to call
Release if I called Resolve, I just don't understand why Castle is
smart enough to call Dispose for me, but not smart enough to release
internal references to my object.

>
> Cheers
> Christian
>
> -------- Original Message --------
> Subject: Re: Some objects created with PerWebRequest are not garbage
>
> collected  at the end of web request.

> From: John Simons <johnsimons...@yahoo.com.au>


> To: castle-pro...@googlegroups.com
> Date: 5/03/2010 2:24 p.m.
> > Maybe you should look at your implementation of the Disposable pattern!
>
> > Run the folowing test without using Windsor:
>
> >         [Test]
> >         public void Test_Disposable_Pattern()
> >         {
> >             var myComponent = new a();
> >             Assert.AreEqual(1, a.counter);
> >             myComponent.Dispose();
> >             GC.Collect();
> >             Assert.AreEqual(0, a.counter);
> >         }
>
> > This fails!
>
> > Seehttp://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx
>
> > Cheers
> > John
>

> > ------------------------------------------------------------------------
> > *From:* mbergal <misha.ber...@gmail.com>
> > *To:* Castle Project Users <castle-pro...@googlegroups.com>
> > *Sent:* Fri, 5 March, 2010 11:32:22 AM
> > *Subject:* Re: Some objects created with PerWebRequest are not garbage


> > collected at the end of web request.
>
> > Thanks a lot, this was a good explanation. unfortunately it still
> > cannot explain the following:
>
> >   public class a : IDisposable
> >         {
> >         public static int counter;
> >         public static int not_disposed_counter;
>
> >         public a()
> >             {
> >             counter++;
> >             not_disposed_counter++;
> >             }
>
> >         ~a()
> >             {
> >             counter--;
> >             }
>
> >         public void Dispose()
> >             {
> >             not_disposed_counter--;
> >             }
> >         }
>
> > with every request counter grows, but not_disposed_counter stays the
> > same.
>
> > So Castle knows enough to dispose objects (basically making them
> > unusable), but still keeps references to them? I just cannot grok it.
> > Why does it need to do it? What about a principle of least surprise?
> > Please help.
>
> > On Mar 4, 4:05 pm, Jason Meckley <jasonmeck...@gmail.com

> > <mailto:jasonmeck...@gmail.com>> wrote:
> > > yes, you should. With MVC frameworks this is all done for you. With
> > > Webforms it gets tedious.
> > > I believe there is also a way to tell Windsor not to track components,
> > > but I haven't used that. I try to stick with the Castle defaults as
> > > much as possible.
> > > I'm not sure if it still exists, but Ayende created Rhino.Igloo as
> > > part of Rhino.Tools. It was available from SVN, I don't think he
> > > ported it to Git though. In any case this was a framework to auto-
> > > inject presenters into the code behind of webforms.
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Castle Project Users" group.
> > To post to this group, send email to
> > castle-pro...@googlegroups.com

> > <mailto:castle-pro...@googlegroups.com>.


> > To unsubscribe from this group, send email to

> > castle-project-u...@googlegroups.com
> > <mailto:unsub...@googlegroups.com>.

John Simons

unread,
Mar 4, 2010, 10:28:18 PM3/4/10
to castle-pro...@googlegroups.com
mbergal,

Castle is releasing internal references if you call Release().

The following test proves it:
        [Test]
        public void Test_That_Release_Is_Really_Releasing()

        {
            using (var container = new WindsorContainer())
            {
                container.Register(Component.For<a>().LifeStyle.Transient);

                var b = container.Resolve<a>();
                Assert.AreEqual(1, a.counter);
                container.Release(b);
                b = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();

                Assert.AreEqual(0, a.counter);
                var d = container.Resolve<a>();
                Assert.AreEqual(1, a.counter);
                container.Release(d);
                d = null;
                GC.Collect();
                GC.WaitForPendingFinalizers();
                Assert.AreEqual(0, a.counter);
            }
        }


From: mbergal <misha....@gmail.com>
To: Castle Project Users <castle-pro...@googlegroups.com>
Sent: Fri, 5 March, 2010 2:22:10 PM
> > castle-project-users+unsub...@googlegroups.com

> > <mailto:unsub...@googlegroups.com>.
> > For more options, visit this group at
> >http://groups.google.com/group/castle-project-users?hl=en.
>
> >   --
> > You received this message because you are subscribed to the Google
> > Groups "Castle Project Users" group.
> > To post to this group, send email to
> > castle-pro...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > castle-project-users+unsub...@googlegroups.com.

> > For more options, visit this group at
> >http://groups.google.com/group/castle-project-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "Castle Project Users" group.
To post to this group, send email to castle-pro...@googlegroups.com.
To unsubscribe from this group, send email to castle-project-users+unsub...@googlegroups.com.

Christian Wuerdig

unread,
Mar 5, 2010, 1:47:02 AM3/5/10
to castle-pro...@googlegroups.com
That's not the problem. His question is: If Windsor is smart enough to call Dispose on an IDisposable object when Release is NOT called then why does it still hold on to it?


-------- Original Message --------
Subject: Re: Some objects created with PerWebRequest are not garbage collected  at the end of web request.
To unsubscribe from this group, send email to castle-project-u...@googlegroups.com.

Jason Meckley

unread,
Mar 5, 2010, 9:02:58 AM3/5/10
to Castle Project Users
this is beyond my understanding of .net and Windsor. I have never
needed/spiked code for a finalizer (~) or explicitly called garbage
collection. I trust Castle and .net to maintain that. maybe you are
just spiking a concept trying to understand what is happening, but why
mess with the finalizer and static value at all?

On Mar 5, 1:47 am, Christian Wuerdig <chris....@gmx.de> wrote:
> That's not the problem. His question is: If Windsor is smart enough to
> call Dispose on an IDisposable object when Release is NOT called then
> why does it still hold on to it?
>
> -------- Original Message --------
> Subject: Re: Some objects created with PerWebRequest are not garbage
>
> collected  at the end of web request.

> Date: 5/03/2010 4:28 p.m.
> > mbergal,
>
> > Castle is releasing internal references if you call Release().
>
> > The following test proves it:
> >         [Test]
> >         public void Test_That_Release_Is_Really_Releasing()
> >         {
> >             using (var container = new WindsorContainer())
> >             {
>
> > container.Register(Component.For<a>().LifeStyle.Transient);
>
> >                 var b = container.Resolve<a>();
> >                 Assert.AreEqual(1, a.counter);
> >                 container.Release(b);
> >                 b = null;
> >                 GC.Collect();
> >                 GC.WaitForPendingFinalizers();
> >                 Assert.AreEqual(0, a.counter);
> >                 var d = container.Resolve<a>();
> >                 Assert.AreEqual(1, a.counter);
> >                 container.Release(d);
> >                 d = null;
> >                 GC.Collect();
> >                 GC.WaitForPendingFinalizers();
> >                 Assert.AreEqual(0, a.counter);
> >             }
> >         }
>

> > ------------------------------------------------------------------------
> > *From:* mbergal <misha.ber...@gmail.com>
> > *To:* Castle Project Users <castle-pro...@googlegroups.com>

> > *Sent:* Fri, 5 March, 2010 2:22:10 PM


> > *Subject:* Re: Some objects created with PerWebRequest are not garbage
> > collected at the end of web request.
>

> > On Mar 4, 7:52 pm, Christian Wuerdig <chris....@gmx.de

> > <mailto:johnsimons...@yahoo.com.au>>
> > > To: castle-pro...@googlegroups.com
> > <mailto:castle-pro...@googlegroups.com>


> > > Date: 5/03/2010 2:24 p.m.
> > > > Maybe you should look at your implementation of the Disposable
> > pattern!
>
> > > > Run the folowing test without using Windsor:
>
> > > >         [Test]
> > > >         public void Test_Disposable_Pattern()
> > > >         {
> > > >             var myComponent = new a();
> > > >             Assert.AreEqual(1, a.counter);
> > > >             myComponent.Dispose();
> > > >             GC.Collect();
> > > >             Assert.AreEqual(0, a.counter);
> > > >         }
>
> > > > This fails!
>
> > > > Seehttp://msdn.microsoft.com/en-us/library/ms244737%28VS.80%29.aspx
>
> > > > Cheers
> > > > John
>
> > ------------------------------------------------------------------------
> > > > *From:* mbergal <misha.ber...@gmail.com

> > <mailto:misha.ber...@gmail.com>>


> > > > *To:* Castle Project Users <castle-pro...@googlegroups.com

> > <mailto:castle-pro...@googlegroups.com>>


> > > > *Sent:* Fri, 5 March, 2010 11:32:22 AM
> > > > *Subject:* Re: Some objects created with PerWebRequest are not garbage
> > > > collected at the end of web request.
>
> > > > Thanks a lot, this was a good explanation. unfortunately it still
> > > > cannot explain the following:
>
> > > >   public class a : IDisposable
> > > >         {
> > > >         public static int counter;
> > > >         public static int not_disposed_counter;
>
> > > >         public a()
> > > >             {
> > > >             counter++;
> > > >             not_disposed_counter++;
> > > >             }
>
> > > >         ~a()
> > > >             {
> > > >             counter--;
> > > >             }
>
> > > >         public void Dispose()
> > > >             {
> > > >             not_disposed_counter--;
> > > >             }
> > > >         }
>
> > > > with every request counter grows, but not_disposed_counter stays the
> > > > same.
>
> > > > So Castle knows enough to dispose objects (basically making them
> > > > unusable), but still keeps references to them? I just cannot grok it.
> > > > Why does it need to do it? What about a principle of least surprise?
> > > > Please help.
>
> > > > On Mar 4, 4:05 pm, Jason Meckley <jasonmeck...@gmail.com
> > <mailto:jasonmeck...@gmail.com>

> > > > <mailto:jasonmeck...@gmail.com <mailto:jasonmeck...@gmail.com>>>


> > wrote:
> > > > > yes, you should. With MVC frameworks this is all done for you. With
> > > > > Webforms it gets tedious.
> > > > > I believe there is also a way to tell Windsor not to track
> > components,
> > > > > but I haven't used that. I try to stick with the Castle defaults as
> > > > > much as possible.
> > > > > I'm not sure if it still exists, but Ayende created Rhino.Igloo as
> > > > > part of Rhino.Tools. It was available from SVN, I don't think he
> > > > > ported it to Git though. In any case this was a framework to auto-
> > > > > inject presenters into the code behind of webforms.
>
> > > > --
> > > > You received this message because you are subscribed to the Google
> > > > Groups "Castle Project Users" group.
> > > > To post to this group, send email to
> > > > castle-pro...@googlegroups.com
> > <mailto:castle-pro...@googlegroups.com>

> > > > <mailto:castle-pro...@googlegroups.com


> > <mailto:castle-pro...@googlegroups.com>>.
> > > > To unsubscribe from this group, send email to

> > > > castle-project-u...@googlegroups.com
> > <mailto:unsub...@googlegroups.com>
> > > > <mailto:unsub...@googlegroups.com


> > <mailto:unsub...@googlegroups.com>>.
> > > > For more options, visit this group at
> > > >http://groups.google.com/group/castle-project-users?hl=en.
>
> > > >   --
> > > > You received this message because you are subscribed to the Google
> > > > Groups "Castle Project Users" group.
> > > > To post to this group, send email to

> > > > castle-pro...@googlegroups.com
> > <mailto:castle-pro...@googlegroups.com>.
> > > > To unsubscribe from this group, send email to

> > > > castle-project-u...@googlegroups.com


> > <mailto:unsub...@googlegroups.com>.
> > > > For more options, visit this group at
> > > >http://groups.google.com/group/castle-project-users?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google
> > Groups "Castle Project Users" group.
> > To post to this group, send email to

> > castle-pro...@googlegroups.com
> > <mailto:castle-pro...@googlegroups.com>.
> > To unsubscribe from this group, send email to

> > castle-project-u...@googlegroups.com


> > <mailto:unsub...@googlegroups.com>.
> > For more options, visit this group at
> >http://groups.google.com/group/castle-project-users?hl=en.
>
> >   --
> > You received this message because you are subscribed to the Google
> > Groups "Castle Project Users" group.
> > To post to this group, send email to
> > castle-pro...@googlegroups.com.
> > To unsubscribe from this group, send email to

mbergal

unread,
Mar 5, 2010, 6:48:06 PM3/5/10
to Castle Project Users
The code above is just a demo of strange/unexpected Windsor behavior.
It uses finalizers for illustration purposes.

My question is:

"If Windsor is smart enough to call Dispose on an IDisposable object
when Release is NOT called then

why does it still hold on to it?" Christian Wuerdig

xtoff

unread,
Mar 6, 2010, 7:20:10 AM3/6/10
to Castle Project Users
Windsor calls dispose when releasing your object. I can't see why this
would behave like this, other than perhaps your dispose throwing an
exception.
Can you post a working reproduction of this issue?

SimoneB

unread,
Mar 6, 2010, 5:03:18 PM3/6/10
to Castle Project Users
Guys, I think MK still has issues with component burden. The
PerWebRequestLifestyle, as it is implemented, actually releases the
component at the end of the request (http://svn.castleproject.org:8080/
svn/castle/InversionOfControl/trunk/src/Castle.MicroKernel/Lifestyle/
PerWebRequestLifestyleManager.cs), but that didn't work for me, and
any disposable dependencies part of the burden of the component being
resolved explicitly from the container didn't get released. I see this
stuff reported several times and no one ever coming up with a
definitive answer, so I would say we have a bug. (http://
groups.google.com/group/castle-project-users/browse_thread/thread/
bd287dd66b3a9d64/)

mbergal

unread,
Mar 7, 2010, 2:07:54 AM3/7/10
to Castle Project Users
Thanks for answering.

http://metacomm-test.s3.amazonaws.com/Castle.Windsor.TestsWeb.rar

You will have to tweak some web.config and IIS settings depending on
what your OS is.

To reproduce the issue, open default.aspx in your web browser and
refresh page several times.

mbergal

unread,
Mar 7, 2010, 2:13:29 AM3/7/10
to Castle Project Users
After brief look at PerWebRequestLifestyleManager.cs, I think the
problem might have a "wider scope" than just PerWebRequestLifestyle.
Even if PerWebRequestLifestyleManager properly released PerWebRequest
root objects, it would still not release transient ones, and IMHO this
might be a even bigger problems.

Krzysztof Koźmic

unread,
Mar 7, 2010, 7:02:50 AM3/7/10
to castle-pro...@googlegroups.com
This obviously is a bug. Please report it to Donjon.

I created a sketchy patch for this
http://github.com/kkozmic/Castle.InversionOfControl
I didn't push it to Castle repository though, as I don't feel confident
about it.
Can you take that version, and see if it works, and pore importantly -
if it causes any regression issues?

cheers,

Krzysztof

mbergal

unread,
Mar 7, 2010, 4:57:34 PM3/7/10
to Castle Project Users
Thanks, this works (not tried it on production code yet though). Now
objects with PerWebRequest lifestyle are properly disposed and
released.

But here is an important question:

If my PerWebRequest objects are disposed and released automatically,
why doesn't Windsor do it for my transient objects created in web
request?

Thanks again.


Krzysztof Koźmic

unread,
Mar 7, 2010, 5:15:34 PM3/7/10
to castle-pro...@googlegroups.com
Windsor does not dispose of your transient objects at the end of request
because end of request means nothing to transient objects.
Windsor does not know you no longer want to use these objects after web
request ends.
If you want to release transient objects use either child
container-per-webrequest or release transient objects yourself.

mbergal

unread,
Mar 7, 2010, 6:11:34 PM3/7/10
to Castle Project Users

On Mar 7, 4:15 pm, Krzysztof Koźmic <krzysztof.koz...@gmail.com>
wrote:


> Windsor does not dispose of your transient objects at the end of request
> because end of request means nothing to transient objects.

Right. I understand this.

> Windsor does not know you no longer want to use these objects after web
> request ends.

Cannot provide a proof of it, but IMHO web request is a natural scope
for transient objects in 99% of cases. Cannot say for other people,
but I would expect Windsor supporting this out of the box.


> If you want to release transient objects use either child

> container-per-webrequest ...


Yes, this is what I am going to do.

SimoneB

unread,
Mar 7, 2010, 7:00:02 PM3/7/10
to Castle Project Users
What do you mean by "transient objects" in this context? Dependencies
of PWR components? In that case I'd expect them to be released as well
as soon as the PWRLifestyleManager releases the PWR ones.

However, I think the issue is still in the objects implementing
IDisposable. misha, in your example if you remove the IDisposable
interface then the finalizer is called correctly.

SimoneB

unread,
Mar 7, 2010, 7:03:18 PM3/7/10
to Castle Project Users

On Mar 7, 11:15 pm, Krzysztof Koźmic <krzysztof.koz...@gmail.com>
wrote:


> Windsor does not dispose of your transient objects at the end of request
> because end of request means nothing to transient objects.

Are we talking about transient objects created to satisfy dependencies
of PWR objects? I'd expect them to be released when the PWR object is
released, that is, as the end of the request. And this is fact
happening until the transient object implements IDisposable. Dispose
is called (as demonstrated by the same app by misha), but then they
are not garbage collected.

Krzysztof Koźmic (2)

unread,
Mar 8, 2010, 3:19:35 AM3/8/10
to Castle Project Users
I was talking about transient root objects.
Transient objects get released when you release them.
PWR objects get released when request ends.

We possibly have a bug WRT PWR objects not playing nice with burden,
which would cause issues described before in this thread.

The patch I created (in my fork of Windsor) appears to be making this
issue go away, we have to investigate it further before applying
though.

Feel free to check out my branch and test if it works for you and most
importantly
if it does not cause any regression issues.
Krzysztof

Simone Busoli

unread,
Mar 8, 2010, 3:15:37 PM3/8/10
to castle-pro...@googlegroups.com
Thanks Krzystof, the only issue I see is that it's difficult to test for regression issues for PWR, but I'll give ti a try.

2010/3/8 Krzysztof Koźmic (2) <krzy...@kozmic.pl>
Reply all
Reply to author
Forward
0 new messages