<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
		>
<channel>
	<title>Comments on: WPF : Dynamic Search Driven List Results</title>
	<atom:link href="http://sachabarber.net/?feed=rss2&#038;p=496" rel="self" type="application/rss+xml" />
	<link>http://sachabarber.net/?p=496</link>
	<description></description>
	<lastBuildDate>Thu, 02 Sep 2010 07:30:57 -0400</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
		<item>
		<title>By: Stephan Keil</title>
		<link>http://sachabarber.net/?p=496&#038;cpage=1#comment-2906</link>
		<dc:creator>Stephan Keil</dc:creator>
		<pubDate>Wed, 10 Jun 2009 07:53:47 +0000</pubDate>
		<guid isPermaLink="false">http://sachabarber.net/?p=496#comment-2906</guid>
		<description>Oops, now my original comment is there again. Sorry for posting the same ideas twice...</description>
		<content:encoded><![CDATA[<p>Oops, now my original comment is there again. Sorry for posting the same ideas twice&#8230;</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Stephan Keil</title>
		<link>http://sachabarber.net/?p=496&#038;cpage=1#comment-2905</link>
		<dc:creator>Stephan Keil</dc:creator>
		<pubDate>Wed, 10 Jun 2009 07:50:18 +0000</pubDate>
		<guid isPermaLink="false">http://sachabarber.net/?p=496#comment-2905</guid>
		<description>Hm, my previous post doesn&#039;t show up, so here is my comment again:

IMO your AppDomain does not avoid the leaks, at least if you mean the leaking of temporary assemblies and Type objects.
Please correct me if I am missing something:

1. While loading the Dyno.dll assembly (line 37: &#039;domain.Load(...)&#039;) into the temporary AppDomain, the assembly is also loaded into the &quot;main&quot; (current) AppDomain. I suppose that is because AppDomain.Load() returns the loaded assembly, which actually serializes/deserializes the assembly from the temporary to the main AppDomain.

2. When unwrapping the object handle (line 48: &#039;instance = instanceHandle.Unwrap()&#039;), the same occurs with the created EnumerableResultsCreator. I.e. it is copied by (de-)serialization from the temporary to the main AppDomain (for this to succeed, the downloaded code correctly has a [Serializable] attribute on EnumerableResultsCreator, which is missing in the code in your post).
All subsequent accesses to the instance then occur in the main AppDomain, thus the temporary AppDomain is actually useless.
For each call to DataLoader.ObtainFlattenedResults(), the invocation of EnumerableResultsCreator.ObtainFlattenedResults() (through reflection, see line 52: &#039;results = instance.GetType()...&#039;) finally uses CSharpCodeProvider.CompileAssemblyFromSource() to compile the dynamic code. The dynamic code actually contains two class types: &#039;ResultsWriter&#039; and the anonymous type from the linq expression.
CompileAssemblyFromSource() creates a dynamic assembly for these types. And as the EnumerableResultsCreator &#039;instance&#039; resides in the main domain, the assemblies are also loaded into that domain. So there is one dynamic assembly with two types for each DataLoader.ObtainFlattenedResults() call =&gt; leak.
You can nicely inspect the effect by setting a break point after &#039;results = instance...&#039; (i.e. line 62 in your code snippet) and watch AppDomain.CurrentDomain.GetAssemblies() growing.

As I understand it there are two options for using an object accross AppDomains:
Either the object is serialized/deserialized from the source domain to the target domain (which needs the respective class to be [Serializable] as in your example), resulting in actually two instances, one per AppDomain. Here unloading the source AppDomain has no effect since the target AppDomain works on a copy of the object.
Or a proxy for the object is created in the target domain (which needs the respective class to derive from MarshalByRefObject). In this case, unloading the source AppDomain invalidates the proxy, so each subsequent call to the proxy will result in an exception.

To develop a dynamic data library for the company I work for (see http://www.quinlogic.com) I was also looking for a way to dynamically create types (classes) which only exist temporarily. For my understanding this can be achieved with a temporary AppDomain, if all accesses to the &quot;dynamic&quot; types are only made in that AppDomain.
This is not very convenient. My favourite approach would be if a dynamically created Type (and its associated code) is (optionally) subject to garbage collection. I.e. the type and its code is collected if the last instance of that type has gone. To my knowledge this is not possible with .NET/CLR.</description>
		<content:encoded><![CDATA[<p>Hm, my previous post doesn&#8217;t show up, so here is my comment again:</p>
<p>IMO your AppDomain does not avoid the leaks, at least if you mean the leaking of temporary assemblies and Type objects.<br />
Please correct me if I am missing something:</p>
<p>1. While loading the Dyno.dll assembly (line 37: &#8216;domain.Load(&#8230;)&#8217;) into the temporary AppDomain, the assembly is also loaded into the &#8220;main&#8221; (current) AppDomain. I suppose that is because AppDomain.Load() returns the loaded assembly, which actually serializes/deserializes the assembly from the temporary to the main AppDomain.</p>
<p>2. When unwrapping the object handle (line 48: &#8216;instance = instanceHandle.Unwrap()&#8217;), the same occurs with the created EnumerableResultsCreator. I.e. it is copied by (de-)serialization from the temporary to the main AppDomain (for this to succeed, the downloaded code correctly has a [Serializable] attribute on EnumerableResultsCreator, which is missing in the code in your post).<br />
All subsequent accesses to the instance then occur in the main AppDomain, thus the temporary AppDomain is actually useless.<br />
For each call to DataLoader.ObtainFlattenedResults(), the invocation of EnumerableResultsCreator.ObtainFlattenedResults() (through reflection, see line 52: &#8216;results = instance.GetType()&#8230;&#8217;) finally uses CSharpCodeProvider.CompileAssemblyFromSource() to compile the dynamic code. The dynamic code actually contains two class types: &#8216;ResultsWriter&#8217; and the anonymous type from the linq expression.<br />
CompileAssemblyFromSource() creates a dynamic assembly for these types. And as the EnumerableResultsCreator &#8216;instance&#8217; resides in the main domain, the assemblies are also loaded into that domain. So there is one dynamic assembly with two types for each DataLoader.ObtainFlattenedResults() call =&gt; leak.<br />
You can nicely inspect the effect by setting a break point after &#8216;results = instance&#8230;&#8217; (i.e. line 62 in your code snippet) and watch AppDomain.CurrentDomain.GetAssemblies() growing.</p>
<p>As I understand it there are two options for using an object accross AppDomains:<br />
Either the object is serialized/deserialized from the source domain to the target domain (which needs the respective class to be [Serializable] as in your example), resulting in actually two instances, one per AppDomain. Here unloading the source AppDomain has no effect since the target AppDomain works on a copy of the object.<br />
Or a proxy for the object is created in the target domain (which needs the respective class to derive from MarshalByRefObject). In this case, unloading the source AppDomain invalidates the proxy, so each subsequent call to the proxy will result in an exception.</p>
<p>To develop a dynamic data library for the company I work for (see <a href="http://www.quinlogic.com)" rel="nofollow">http://www.quinlogic.com)</a> I was also looking for a way to dynamically create types (classes) which only exist temporarily. For my understanding this can be achieved with a temporary AppDomain, if all accesses to the &#8220;dynamic&#8221; types are only made in that AppDomain.<br />
This is not very convenient. My favourite approach would be if a dynamically created Type (and its associated code) is (optionally) subject to garbage collection. I.e. the type and its code is collected if the last instance of that type has gone. To my knowledge this is not possible with .NET/CLR.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: sacha</title>
		<link>http://sachabarber.net/?p=496&#038;cpage=1#comment-2904</link>
		<dc:creator>sacha</dc:creator>
		<pubDate>Wed, 10 Jun 2009 07:44:56 +0000</pubDate>
		<guid isPermaLink="false">http://sachabarber.net/?p=496#comment-2904</guid>
		<description>Stephan 

These are some excellent comments.

And to be honest I was under the impression that you could unload and appDomain and it would also unload any items that were dynamically loaded into it.

I shall have to look into this a bit further. Ill try and do that soon and write my findings here.

Thanks for pointing this out.</description>
		<content:encoded><![CDATA[<p>Stephan </p>
<p>These are some excellent comments.</p>
<p>And to be honest I was under the impression that you could unload and appDomain and it would also unload any items that were dynamically loaded into it.</p>
<p>I shall have to look into this a bit further. Ill try and do that soon and write my findings here.</p>
<p>Thanks for pointing this out.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: Stephan Keil</title>
		<link>http://sachabarber.net/?p=496&#038;cpage=1#comment-2898</link>
		<dc:creator>Stephan Keil</dc:creator>
		<pubDate>Tue, 09 Jun 2009 23:27:45 +0000</pubDate>
		<guid isPermaLink="false">http://sachabarber.net/?p=496#comment-2898</guid>
		<description>Sorry, but I don&#039;t get the trick of using a separate AppDomain.Can you please explain which kind of memory leaks it avoids?

IMO the AppDomain - as you use it - still leaks in dynamic assemblies and the type objects in these assemblies:

1. &#039;domain.Load()&#039; loads the dyno.dll into the temporary AppDomain. But as a side effect of returning the loaded assembly, the AppDomain.Load() also serializes/deserializes dyno.dll into the current (&quot;main&quot;) AppDomain.

2. When calling &#039;instanceHandle.Unwrap()&#039;, the &#039;EnumerableResultsCreator&#039; object is deserialized/serialized into the current (main) AppDomain (for this to succeed the download code correclty contains the necessary [Serializable] attribute which is omitted in the snipped of your post).
Thus the now unwrapped &#039;EnumerableResultsCreator&#039; instance (along with its type object) lives in the main AppDomain and so do the classes dynamically compiled during &#039;ObtainFlattenedResults&#039;.
To see the effect you can set a breakpoint right after the &#039;results = ...&#039; in DataLoader.ObtainFlattenedResults (line 62 in your code snippet) and watch AppDomain.CurrentDomain.GetAssemblies() growing. For each call to DataLoader.ObtainFlattenedResults() a new assembly containing the dynamically compiled types is added to the domain.

As I understand it, you simply cannot unload an AppDomain and still use an object residing in that domain.
Either the object does not &quot;really&quot; reside in the AppDomain, but has been serialized/deserialized into the calling AppDomain (which needs the respective class to be [Serializable], as your EnumerableResultsCreator); or the object is accessed through a proxy (which needs the respective class to derive from MarshalByRefObject). In the latter case the proxy is &quot;dead&quot; after unloading the AppDomain.

A real nice feature to support dynamic applications would be that Type objects and the code associated with them would be (optionally?) subject to garbage collection. I.e. the Type and code is unloaded as soon as the last instance of that type is gone. But - AFAIK - this is not possible in .NET/CLR.</description>
		<content:encoded><![CDATA[<p>Sorry, but I don&#8217;t get the trick of using a separate AppDomain.Can you please explain which kind of memory leaks it avoids?</p>
<p>IMO the AppDomain &#8211; as you use it &#8211; still leaks in dynamic assemblies and the type objects in these assemblies:</p>
<p>1. &#8216;domain.Load()&#8217; loads the dyno.dll into the temporary AppDomain. But as a side effect of returning the loaded assembly, the AppDomain.Load() also serializes/deserializes dyno.dll into the current (&#8221;main&#8221;) AppDomain.</p>
<p>2. When calling &#8216;instanceHandle.Unwrap()&#8217;, the &#8216;EnumerableResultsCreator&#8217; object is deserialized/serialized into the current (main) AppDomain (for this to succeed the download code correclty contains the necessary [Serializable] attribute which is omitted in the snipped of your post).<br />
Thus the now unwrapped &#8216;EnumerableResultsCreator&#8217; instance (along with its type object) lives in the main AppDomain and so do the classes dynamically compiled during &#8216;ObtainFlattenedResults&#8217;.<br />
To see the effect you can set a breakpoint right after the &#8216;results = &#8230;&#8217; in DataLoader.ObtainFlattenedResults (line 62 in your code snippet) and watch AppDomain.CurrentDomain.GetAssemblies() growing. For each call to DataLoader.ObtainFlattenedResults() a new assembly containing the dynamically compiled types is added to the domain.</p>
<p>As I understand it, you simply cannot unload an AppDomain and still use an object residing in that domain.<br />
Either the object does not &#8220;really&#8221; reside in the AppDomain, but has been serialized/deserialized into the calling AppDomain (which needs the respective class to be [Serializable], as your EnumerableResultsCreator); or the object is accessed through a proxy (which needs the respective class to derive from MarshalByRefObject). In the latter case the proxy is &#8220;dead&#8221; after unloading the AppDomain.</p>
<p>A real nice feature to support dynamic applications would be that Type objects and the code associated with them would be (optionally?) subject to garbage collection. I.e. the Type and code is unloaded as soon as the last instance of that type is gone. But &#8211; AFAIK &#8211; this is not possible in .NET/CLR.</p>
]]></content:encoded>
	</item>
	<item>
		<title>By: tawani</title>
		<link>http://sachabarber.net/?p=496&#038;cpage=1#comment-2776</link>
		<dc:creator>tawani</dc:creator>
		<pubDate>Sat, 16 May 2009 23:25:06 +0000</pubDate>
		<guid isPermaLink="false">http://sachabarber.net/?p=496#comment-2776</guid>
		<description>Sacha,
Nice and simple approach.
A better way (and much easier/flexible) to display dynamic search results will be to bind the ListView to a DataMatrix. You can check out this approach from my article on the CodeProject.
http://www.codeproject.com/KB/WPF/WPF_DynamicListView.aspx</description>
		<content:encoded><![CDATA[<p>Sacha,<br />
Nice and simple approach.<br />
A better way (and much easier/flexible) to display dynamic search results will be to bind the ListView to a DataMatrix. You can check out this approach from my article on the CodeProject.<br />
<a href="http://www.codeproject.com/KB/WPF/WPF_DynamicListView.aspx" rel="nofollow">http://www.codeproject.com/KB/WPF/WPF_DynamicListView.aspx</a></p>
]]></content:encoded>
	</item>
</channel>
</rss>
