<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Dario Airoldi TechNotes</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/darioa/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/darioa/feed.xml</link>
    <description />
    <lastBuildDate>Tue, 16 Apr 2019 04:58:01 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Boost WCF performance using adaptive encoding</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/boost-wcf-performance-using-adaptive-encoding</link>
      <pubDate>Fri, 18 Nov 2011 12:00:00 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2011/11/18/boost-wcf-performance-using-adaptive-encoding/</guid>
      <description><![CDATA[Authors: Dario Airoldi, Paolo Zavatarelli
Abstract
Interesting documentation can be found...]]></description>
      <content:encoded><![CDATA[<p><span style="color: #000000; font-size: medium;" size="4"><span color="#4f81bd"><span style="font-family: Cambria;" face="Cambria"><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Authors: Dario Airoldi, Paolo Zavatarelli</span></span></span></span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Abstract</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Interesting documentation can be found comparing the many options available in WCF to encode web services data. Any encoding strategy may have advantages and disadvantages in different environments and runtime conditions.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For example, <b>binary encoding</b> provides best performance on fast network connections, <b>text encoding</b> may be easier to debug and a <b>custom compressed encoding</b> may be better for big messages and slow network connections.</span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">On the other side, a custom compressed encoding uses much CPU and may not be appropriate when the server is very busy; also, it would be completely useless for small messages or messages with data already compressed (i.e. images in a compressed format like jpg).</span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Then, an interesting point is:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Is it possible to make the choice at runtime, and select the most appropriate encoding for each specific condition?</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In fact it is, and you may get interesting performance benefits from such approach!</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this article we&rsquo;ll show how to create a <b>custom DynamicEncoder</b> that <b>extends existing encoders</b> (such as WCF binaryMessageEncoding, textMessageEncoding etc.) selecting the most appropriate at runtime and <b>applies compression selectively</b> to the encoded stream to minimize calls latency and maximize their throughput.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Why adaptive encoding?</span></span></span></h2>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">In the following </span><span style="color: #0000ff; font-family: Calibri; font-size: small;" size="3" color="#0000ff" face="Calibri"><a href="https://blogs.msdn.com/b/dmetzgar/archive/2011/03/22/gzipmessageencoder-part-four.aspx" target="_blank">link</a></span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">, Dustin Metzger proposes a very interesting analysis on the effect you may obtain applying compression to standard WCF binary encoding.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">What seems evident by the numbers is that compression provides such a <b>great benefit</b> on medium and low bandwidth network connections at the cost of an <b>even greater negative impact </b>on high bandwidth network connections. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For example, some measures taken by Dustin show that adding compression to a binary encoded stream may provide significant benefit on a 100 Mbps network where <b>the cost of invocations may be reduced by up to 4 times</b>.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2185.Figure1%20Dustin%20Graph%201.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2185.Figure1-Dustin-Graph-1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2185.Figure1%20Dustin%20Graph%201.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2185.Figure1-Dustin-Graph-1.png" width="452" height="332" /></a></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 1: Throughput comparison, from Dustin Metzger article, between WCF binary encoding and compressed binary encoding on a 100 Mbps network, for different message sizes </span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Understandably, <b>such benefit may grow by far on production environments</b> where it&rsquo;s common to find network bandwidths close to one megabit.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Dustin graph shows however that <b>compressing small messages doesn&rsquo;t really pay off the CPU and latency spent for compression</b>. Also, the following graph from Dustin article shows that with high bandwidth networks or generally with <b>CPU bound loads</b> the cost of compressed encoding may outgrow the cost of standard binary encoding <b>up to 5 times</b>.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8105.Figure1%20Dustin%20Graph%202.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8105.Figure1-Dustin-Graph-2.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8105.Figure1%20Dustin%20Graph%202.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8105.Figure1-Dustin-Graph-2.png" width="456" height="361" /></a></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 2: Throughput comparison, from Dustin Metzger article, between WCF binary encoding and compressed binary encoding on a 1 Gbps network, for different message sizes</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Again, in real production environments you may find <b>messages with images, pdf or xps documents that are already compressed</b> so, compressing their stream at the encoder level wouldn&rsquo;t provide any benefit.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For these reasons we chose to <b>use an adaptive approach</b> and <b>we</b> <b>wrote an encoder</b> (DynamicEncoder) <b>to extend binary encoding</b> <b>that applies compression to the encoded stream selectively</b>, based on few basic rules:</span></span></p>
<ul>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"><b>Compression should be avoided for small messages</b>.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Compression should be disabled automatically <b>when the server CPU load is too high</b>.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Compression should be disabled automatically <b>for soap actions providing messages with bad compression ratio</b>.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>To avoid compressing small messages</b> we chose to allow the configuration of <b>size</b> <b>thresholds for the different compression levels</b>:</span></span></p>
<p><img style="border: 0px currentColor;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0118.Code1%20Config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0118.Code1-Config.png" width="465" height="88" /></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In particular, DynamicEncoder avoids compressing messages with size below the value configured as <b>NoCompressionLimit</b>. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In the example above, the encoder is configured to avoid compression for all messages below 1024 KB and compress other messages with Fast Compression; thresholds for Normal and Maximum compression are set to -1 so they are not considered by the encoder.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>To prevent compression on CPU bound load</b> we chose to allow the configuration of an additional threshold:</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"></span></span><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2502.Code2%20Config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2502.Code2-Config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2502.Code2%20Config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2502.Code2-Config.png" width="348" height="43" /></a>&nbsp;</p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">When the machine CPU load overtakes the CPUDisableLimit <b>DynamicEncoder falls back progressively to standard binary encoding</b>. In the example above, the encoder is configured to disable compression progressively when the server CPU usage outgrows the value of 70%.</span></span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>To prevent compression of uncompressible messages</b> we chose to allow configuration of a last setting:</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4431.Code3%20Config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4431.Code3-Config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4431.Code3%20Config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4431.Code3-Config.png" width="431" height="40" /></a></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">According to this setting, our <b>dynamicEncoder</b> <b>will fall back to standard binary encoding</b> on every invocation that shows an insufficient compression ratio. In the example above, the encoder is configured to disable compression for all soap Actions that show a compression ratio above the value of 70%.</span></span></p>
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The evaluation of the compression ratio for an outgoing message is based on the average ratio produced&nbsp;by the last&nbsp;messages with similar size, in the same soap Action.</span></span></b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"> this means</span></span><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"> that messages with similar sizes, in the same soap action are assumed to produce similar compression ratios.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">So, dynamicEncoder starts compressing messages for all soap Actions. Soap Actions that produce a compression ratio worse than the threshold defined by </span>"<span style="color: #0000ff;">CompressionRatioDisableLimit</span>" <span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">are then disabled progressively.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">This setting is very important because it allows DynamicEncoder disable compression on big complex messages that contain images or documents that are already compressed. Compressing them would waste a lot of CPU Usage&nbsp;and time without producing any benefit. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The following paragraph shows some measures of the performance we obtained with dynamicEncoder. We&rsquo;ll then delve into few details of dynamicEncoder implementation.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Some measures of DynamicEncoder performance</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this section we compare <b>dynamicEncoder</b> performance to <b>WCF binary encoding</b> with different message types and network conditions.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">More specifically, we measure <b>throughput</b> and <b>CPU usage</b> obtained by a sample service returning messages of different sizes and complexities, respectively on a <b>100 Mbps </b>and a <b>1.5 Mbps</b> networks.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The performance measures are taken with <b>3 separate configurations</b> for the service endpoint:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Binary encoding</b>: here the service is configured with <b>WCF binary encoding</b>; the values in this measure serve as a comparison to understand the impact of the compression strategies.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Static compression</b>: in this case the service is configured using <b>dynamicEncoder</b> with <b>CompressionRatioDisableLimit=1</b> and <b>NoCompressionLimit=0</b>. This way compression is applied to all messages returned by the service to the client.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Adaptive compression</b>: here the service is configured using <b>dynamicEncoder</b> with <b>CompressionRatioDisableLimit=0.7</b> and <b>NoCompressionLimit=1024</b>. This way compression is not applied to small messages and it is disabled on messages with bad compression ratio.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The different encoding strategies are compared configuring the sample service to return the following<b> message types</b>:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Simple messages</b>: these are messages with high redundancy; they are compressible by ten times on average (i.e. compression ratio close to <b>0.1</b>).</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Medium complexity messages</b>: these are messages with average redundancy; they are compressible by a factor close to <b>0.4</b>.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Complex messages</b>: these are messages with low redundancy i.e. compressible by a factor <b>between 0.8 and 1</b>.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The measures were taken with random message sizes ranging between <b>0.6KB to 250KB</b> on a distribution with most messages close to 150KB. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">On a <b>100 Mbps network</b> we observed the following results:</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5428.Graph1%20throughput%20comparison%20100.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5428.Graph1-throughput-comparison-100.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5428.Graph1%20throughput%20comparison%20100.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5428.Graph1-throughput-comparison-100.png" /></a></span></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 3: Throughput values produced by adaptive compression, static compression and binary encoding on a 100 Mbps network</span></span></strong></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3146.Graph2%20CPU%20comparison%20100.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3146.Graph2-CPU-comparison-100.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3146.Graph2%20CPU%20comparison%20100.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3146.Graph2-CPU-comparison-100.png" /></a></span></span></strong></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 4: CPU usage produced by adaptive compression, static compression and binary encoding on a 100 Mbps network</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Figure 3 show that <b>all encoding strategies provide similar throughput for complex messages</b>. Indeed, complex messages produce a bad compression ratio so, only few bytes are saved when compressing them. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Figure 4 shows <b>however</b> that <b>static compression wastes a lot of CPU usage</b> for this case.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Adaptive compression instead, gives up compressing complex messages and saves the precious CPU resource for a better use</b>. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">This approach pays well in the other scenarios (and in real production environments) where the <b>CPU </b>is a more precious resource and <b>adaptive compression is able to produce better throughput with lower CPU usage</b>.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">You may notice that only the <b>test with</b> <b>simple messages was bound by CPU usage</b> (i.e. CPU usage reached 100%) while all other measures <b>were bound by network usage</b>; Understandably, on a <b>1.5 Mbps network</b> the bottleneck is always the network usage and the measures produced a similar pattern with much lower CPU usage and throughput values.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">It&rsquo;s great to get this better throughput but <b>what about latencies?</b> </span></span></p>
<p><b><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">How does the time spent for compressing messages compare to the time saved during transmission?</span></span></b></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Given the <b>network speed</b>, the <b>compression speed</b> of a system and the <b>compression ratio</b> obtained on messages it is easy to calculate the <b>time saved for transmission</b> and the <b>time spent for compression</b>:</span></span></p>
<ul>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">TransmissionTimeSaved = messageSize *(1-compressionRatio) / networkSpeed</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">CompressionTimeCost = messageSize *2 / compressionSpeed</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">On our test systems we measured an <b>average compression speed</b> from&nbsp;<b>few KB/sec</b> for smallest messages up to <b>50 MB/sec</b> for biggest messages, with an <b>average compression ratio</b> of <b>0.24</b>. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">On a <b>100MB network</b> you may experience benefits in latency only for bigger messages, when the compression speed is higher.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2577.Figure5%20Netspeed%20100.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2577.Figure5-Netspeed-100.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2577.Figure5%20Netspeed%20100.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2577.Figure5-Netspeed-100.png" width="327" height="54" /></a></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6763.Figure5%20CompSpeed%20100.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6763.Figure5-CompSpeed-100.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6763.Figure5%20CompSpeed%20100.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6763.Figure5-CompSpeed-100.png" /></a></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 5: Latency improvement applying compression to messages on 100MBit networks</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In this scenario, to avoid latency penalties it may be appropriate to raise the <b>NoCompressionLimit setting</b> and apply compression only to bigger messages.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">On a <b>1.5MB network</b> you get more interesting results with a latency benefit from smaller messages.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6786.Figure6%20NetSpeed%201.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6786.Figure6-NetSpeed-1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6786.Figure6%20NetSpeed%201.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6786.Figure6-NetSpeed-1.png" width="326" height="61" /></a></span></p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0638.Figure6%20CompSpeed%201.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0638.Figure6-CompSpeed-1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0638.Figure6%20CompSpeed%201.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0638.Figure6-CompSpeed-1.png" /></a><br /><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 6: Latency improvement applying compression to messages on 1.5MBit networks</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Figure 6 shows that, in this scenario, both messages produce a <b>transmission time improvement of 75%</b>, with absolute latency improvement of <b>2 seconds</b> for the bigger one.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Some measures on DynamicEncoder benefits in a production environment</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Luckily enough, we could measure some benefits on our production systems too. &nbsp;</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In our case, messages have the following distribution with sizes between <b>100B</b> and <b>500KB.</b></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0647.Graph3%20Message%20size.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0647.Graph3-Message-size.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0647.Graph3%20Message%20size.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0647.Graph3-Message-size.png" /></a></span></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 7: Message size distribution for our production environment</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In such scenario, <b>dynamic encoder ends up to apply compression to about half the messages</b> with an <b>average compression ratio of 0.22.</b> <b>Overall, the network traffic is reduced by a factor 0.31</b>.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7752.Figure8%20CompRatio%201.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7752.Figure8-CompRatio-1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7752.Figure8%20CompRatio%201.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7752.Figure8-CompRatio-1.png" /></a></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 8: messages compression ratio obtained by dynamicEncoder on our production environment</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">It is important to notice that in this production environment we have tested the compression provided by the <b>dynamicEncoder </b>over the <b>WCF Binary Encoding</b>. Even if Binary Encoding is a quite efficient way the transmit data on the network, the <b>dynamicEncoder </b>has shown a significant<b> </b>decrease in the network traffic. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Clearly the usage of the<b> dynamicEncoder </b>over the <b>WCF Text Encoding</b>, can demonstrate much better results.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For most clients, the available bandwidth to the server is around <b>2Mbit</b> so the expected latency improvement may range between <b>a</b> <b>few milliseconds</b> for smallest messages up to a <b>couple of seconds</b> for the largest.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">WCF Encoders creation process</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Writing a WCF encoder is just a matter of writing 4 classes, each one creating the other, the last of which (the encoder) does the job of translating incoming messages into the binary arrays sent over the wire.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Two classes of them, a <b>BindingElementExtension</b> and a <b>MessageEncodingBindingElemen</b>t class, are used to load the encoder configuration from the WCF endpoint configuration. A third <b>MessageEncoderFactory</b> class is needed to support the encoder creation process, according to the factory pattern. The last <b>MessageEncoder</b> class, which is the actual encoder, contains the code to translate WCF messages into binary arrays.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The figure below shows the classes involved into the encoder creation process and the message encoder working on a WCF method call.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8103.Figure9%20Encoder%20Arch%201.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8103.Figure9-Encoder-Arch-1.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8103.Figure9%20Encoder%20Arch%201.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8103.Figure9-Encoder-Arch-1.png" /></a></span></p>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 9: classes involved into a WCF encoder creation</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">To write our <b>DynamicEncoder</b> we will then follow the following steps:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Create a <b>DynamicEncoderBindingElementExtension</b> class</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DynamicEncoderBindingElementExtension class must derive from BindingElementExtensionElement; it loads the encoder configuration from the binding configuration and participates to the binding elements creation.</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Create a <b>DynamicEncoderMessageBindingElement</b> class </span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DynamicEncoderMessageBindingElement must derive from MessageEncodingBindingElement and will be invoked by WCF to obtain MessageEncderFactory instances.</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Create a <b>DynamicEncoderFactory</b> class </span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DynamicEncoderFactory class is used by WCF to generate encoder instances according to the factory pattern. The factory is invoked by WCF to obtain message encoder instances whenever needed.</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Create a <b>DynamicEncoder</b> class to do the encoding.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The message encoder job is to translate the WCF Message object into a buffer to be sent over the wire.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Once written, we&rsquo;ll be able to activate <b>DynamicEncoder</b> on a WCF endpoint with few configuration steps:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Declare the <b>DynamicEncoderBindingElementExtension</b> in the <b>extensions node</b> of application configuration file:</span></span></li>
</ul>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<p style="padding-left: 30px;"><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0083.Figure10%20dynencoder%20config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0083.Figure10-dynencoder-config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0083.Figure10%20dynencoder%20config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0083.Figure10-dynencoder-config.png" /></a></span></p>
</div>
</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px;"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 10: dynamicEncoder definition in the application configuration file</span></span></strong>&nbsp;</p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Add a custom binding configuration to a <b>WCF server endpoint</b> with a reference to our dynamicEncoder binding element extension:</span></span></li>
</ul>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<p style="padding-left: 30px;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8468.Figure11%20dynencoder%20config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8468.Figure11-dynencoder-config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8468.Figure11%20dynencoder%20config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8468.Figure11-dynencoder-config.png" /></a></p>
</div>
</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px;"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 11: dynamicEncoder binding element extension configured into a server side endpoint</span></span></strong></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Add a symmetric configuration to its corresponding <b>WCF client endpoint</b>:</span></span></li>
</ul>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre style="padding-left: 30px;"><span style="font-size: x-small;" size="2"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4087.Figure12%20dynencoder%20config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4087.Figure12-dynencoder-config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4087.Figure12%20dynencoder%20config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4087.Figure12-dynencoder-config.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p style="padding-left: 30px;"><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figura 12: dynamicEncoder binding element extension configured into a client side endpoint</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In the configuration examples above <b>dynamicEncoder</b> is configured to work with two <b>inner encodings</b> (<b>BinaryMessageEncoding</b> and <b>TextMessageEncoding</b>) using <b>BinaryMessageEncoding</b> as the default.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">This means that any client endpoint with <b>BinaryMessageEncoding</b> will be able to talk to the server without changes; of course, only client endpoints configured with our <b>dynamicEncoder</b> will be able to leverage the performance benefits of <b>adaptive encoding</b> and <b>selective compression</b>.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For this reason we&rsquo;ll say that <b>DynamicEncoder extends the message encoding specified as the default</b>.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Step 1: Create a DynamicEncoderBindingElementExtension class</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The role of a <b>binding element extension</b> is to deserialize a binding element configuration and expose WCF the methods to create its associated <b>binding element</b>.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DynamicEncoderBindingElementExtension&nbsp;inherits from BindingElementExtensionElement as shown below: </span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8473.Figure13%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8473.Figure13-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8473.Figure13%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8473.Figure13-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figura 13: DynamicEncoderBindingElementExtension definition</span></span></strong></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">As shown in Figure 11 and 12 we use few properties to allow nesting the configuration of the inner encodings within the configuration of DynamicEncoderBindingElementExtension:</span></span></p>
<ul>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>BinaryMessageEncoding</b>,<b> TextMessageEncoding</b> and <b>MtomMessageEncoding</b> are used to configure the supported inner message encoders</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>DefaultMessageEncoding</b> is used to define the one used by default.</span></span></li>
</ul>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-size: x-small;" size="2"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8461.Figure14%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8461.Figure14-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8461.Figure14%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8461.Figure14-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 14: DynamicEncoderBindingElementExtension properties to deserialize inner encodings configuration</span></span></strong></pre>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">3 additional properties (<b>Providers, Algorithms and Levels</b>) are used to configure <b>compression</b> <b>providers</b>, <b>algorithms</b> and <b>compression levels</b> allowed for the encoder.</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-size: x-small;" size="2">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6835.Figure15%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6835.Figure15-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6835.Figure15%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6835.Figure15-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figure 15: DynamicEncoderBindingElementExtension properties to deserialize compression settings</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">By default, our DynamicEncoder uses <b>one compression provider</b> (CLR) based on .Net System.Compression libraries. </span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Step 2: Create a DynamicEncoderMessageBindingElement class</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Our DynamicEncoderMessageBindingElement class needs to <b>deliver inner encoders and compression configuration</b> from the binding element extension <b>to the encoder factory and DynamicEncoder</b> instances.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">For this reason, we&rsquo;ll design it with a structure similar to that of DynamicEncoderBindingElementExtension.</span></span><span style="font-family: Courier New; font-size: x-small;" size="2" face="Courier New"> </span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7080.Figure16%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7080.Figure16-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7080.Figure16%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7080.Figure16-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre>&nbsp;</pre>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3288.Figure16a%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3288.Figure16a-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3288.Figure16a%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3288.Figure16a-dynencoder-code.png" /></a> </pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figura 16: DynamicEncoderBindingElement properties to hold inner encodings and compression settings</span></span></strong></pre>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">To get encoder factories from the binding element WCF will use the following entry point:</span>&nbsp;</span><span style="font-family: Courier New; font-size: x-small;" size="2" face="Courier New"> </span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-size: x-small;" size="2"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1856.Figure17%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1856.Figure17-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1856.Figure17%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1856.Figure17-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre><strong><span style="font-family: Calibri;" face="Calibri"><span style="color: #4f81bd;" color="#4f81bd">Figura 17: Encoder factory creation entry point</span></span></strong></pre>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Step 3: Create a DynamicEncoderFactory class</span></span></span></h2>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">The factory class role is to prepare everything possible to allow efficient encoder instantiation, according to the endpoint configuration.</span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">So, we&rsquo;ll design our factory class to hold factories instances for the inner encoders:</span></span></p>
<ul>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"><b>InnerFactories</b> collection is used to keep the instances of encoder factories necessary to obtain inner encoders.</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>DefaultMessageEncoding</b> property used to define the one used by default.</span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Inner factories and other configuration information is taken from the binding element received at construction time</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4786.Figure18%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4786.Figure18-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/4786.Figure18%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/4786.Figure18-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figura 18: encoder factory construction time</span></span></strong></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">As usual, few properties are used to hold inner encoder factory instances and compression configuration</span></span><span style="font-family: Courier New; font-size: x-small;" size="2" face="Courier New"> </span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0777.Figure19%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0777.Figure19-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0777.Figure19%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0777.Figure19-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre><strong><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Calibri;" face="Calibri">Figura 19: inner encoders factory instances and compression configuration into DynamicEncoderFactory</span></span></strong></pre>
<pre><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">WCF will then be able to get encoder instances by means of Encoder property (for sessionless connections) and CreateSessionEncoder method.</span></span><span style="font-family: Courier New; font-size: x-small;" size="2" face="Courier New"> </span></pre>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2620.Figure20%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2620.Figure20-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2620.Figure20%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2620.Figure20-dynencoder-code.png" /></a> </pre>
</div>
</td>
</tr>
</tbody>
</table>
<pre><strong><span style="font-family: Calibri;" face="Calibri"><span style="color: #4f81bd;" color="#4f81bd">Figura 20: DynamicEncoderFactory entry points used to deliver encoder instances to WCF</span></span></strong></pre>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">Step 4: Create a DynamicEncoder class to do the encoding</span></span></span></h2>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The DynamicEncoder class is the <b>real WCF encoder</b> class. At every service call WCF will make sure that our encoder be loaded and initialized by means of the encoder creation process described up to now.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">As every WCF encoder, DyanmicEncoder class inherits from MessageEncoder class.</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7127.Figure20a%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7127.Figure20a-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7127.Figure20a%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7127.Figure20a-dynencoder-code.png" /></a> </pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Not surprisingly, DynamicEncoder class will hold inner encoder instances, the default encoder and configuration settings about compression providers, algorithms and levels configured for the endpoint.&nbsp; </span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2843.Figure20b%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2843.Figure20b-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2843.Figure20b%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2843.Figure20b-dynencoder-code.png" /></a> </pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Any information necessary for operating is received by the encoder at construction time, from the factory object.</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1638.Figure20c%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1638.Figure20c-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1638.Figure20c%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1638.Figure20c-dynencoder-code.png" /></a></p>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DynamicEncoder performs few basic tasks:</span></span></p>
<ol>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">It <b>chooses what encoding algorithm should be used</b> to encode the message</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">It uses the selected inner encoder to encode the message into a binary stream</span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">It <b>chooses whether the encoded stream should be compressed and what algorithm should be applied</b></span></span></li>
<li><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">In case, It applies compression to the binary stream</span></span></li>
</ol>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Such tasks are performed into its <b>WriteMessage overrides</b>, by means of <b>some provider classes</b> that are loaded statically:</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5241.Figure20d%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5241.Figure20d-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5241.Figure20d%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5241.Figure20d-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">One or more <b>compression providers</b> expose compression algorithms to the encoder by means of <b>IDataCompressor</b> interface.&nbsp; <b>DynamicEncoder supports use of multiple compression provider classes</b>; by default, DynamicEncoder uses DataCompressor class: a very simple compression provider, based on .Net framework System.Compression libraries. </span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<pre><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8461.Figure20e%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8461.Figure20e-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/8461.Figure20e%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/8461.Figure20e-dynencoder-code.png" /></a></span></pre>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">DataCompressor provider supports <b>GZip and Deflate algorithms</b> with <b>only one compression level</b>.&nbsp; Additional providers supporting different compression levels may be added easily.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">One <b>encoder selector</b> class contains all the rules for choosing the inner encoder and the compression settings to apply to the encoded stream.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The encoder selector exposes to the encoder such rules by means of interface <b>IDynamicEncoderSelector</b>.</span></span></p>
<table style="width: 100%;" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td>
<div>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2018.Figure20f%20dynencoder%20code.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2018.Figure20f-dynencoder-code.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/2018.Figure20f%20dynencoder%20code.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/2018.Figure20f-dynencoder-code.png" /></a></p>
</div>
</td>
</tr>
</tbody>
</table>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>Initialize() </b>and <b>Clone()</b> are used by DynamicEncoder to initialize selector instances for any WCF channel.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>OnSelectEncoder()</b>, <b>OnSelectAlgorithm()</b> are invoked to choose the inner encoding and the compression settings to apply to the compressed stream.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"><b>OnEncodeComplete()</b> is invoked after compression to allow gathering information on the encoded call that can be used to adapt encoder choices to the runtime conditions.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">OnEncodeComplete()&nbsp; is <b>used by the default EncoderSelector to gather information about the compression ratio obtained on outgoing messages</b>. This information is used by <b>EncoderSelector</b> to honor </span>CompressionRatioDisableLimit<span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri"> setting.</span></span></p>
<h2><span style="font-size: medium;" size="4"><span style="color: #4f81bd;" color="#4f81bd"><span style="font-family: Cambria;" face="Cambria">References</span></span></span></h2>
<ul>
<li><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">Dustin Metzgar: Compressing messages in WCF part four - Network performance<br /></span><a href="https://blogs.msdn.com/b/dmetzgar/archive/2011/03/22/gzipmessageencoder-part-four.aspx" target="_blank"><span style="color: #0000ff; font-family: Calibri; font-size: small;" size="3" color="#0000ff" face="Calibri">https://blogs.msdn.com/b/dmetzgar/archive/2011/03/22/gzipmessageencoder-part-four.aspx</span></a></li>
</ul>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/23/86/61/CalculatorClient.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-23-86-61/CalculatorClient.zip">CalculatorClient.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Key reasons why use WPF on a Business Application</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/key-reasons-why-use-wpf-on-a-business-application</link>
      <pubDate>Fri, 02 Jan 2009 18:00:52 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2009/01/02/key-reasons-why-use-wpf-on-a-business-application/</guid>
      <description><![CDATA[For some time, there has been discussion on whether WPF may be a good choice for writing Business...]]></description>
      <content:encoded><![CDATA[<p>For some time, there has been discussion on whether WPF may be a good choice for writing Business Applications. Typical reasons against using it are that <strong>Business Applications do not require graphic capabilities</strong>, WPF is quite a new technology, <strong>it requires time to learn</strong>, and it may be <strong>slower than other technologies on obsolete hardware</strong>. These may still be good reasons for you even considering that WPF was released more than a couple of years ago, it has improved on performance with its updates and new releases and it begins to be widely used in every type of applications.
</p><p>Well, after a while working with WPF I could understand and experience some key reasons why WPF is really worth using, in every business application.
</p><h2>Reason n° 1: Functional Analysts and Graphic designers may define the user interfaces by means of XAML instead of bitmaps.
</h2><p>With older technologies, functional analysis and graphic designs used to be defined with documents and images; It was the developer work to translate all that in code. 
</p><p>WPF allows using XAML since functional analysis and graphic design stages. This way, part of the developer work is already done and many misunderstandings can be avoided.
</p><h2>Reason n° 2: C# code is significantly reduced.
</h2><p>Writing WPF applications, <strong>C# code</strong> is only necessary to access and manage business data. All the data rendering is managed by the <strong>User Interface XAML</strong> and <strong>WPF Data Binding</strong> tags and attributes. C# code no longer needs to manage user controls and their properties as all the rendering logic is into the XAML. So, the application code is generally reduced significantly.
</p><p>The example below shows a complex form that manages data in a business entity:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image001_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image001_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image001_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image001_thumb.png" alt="" border="0"/></a>
	</p><p><strong>Figure 1</strong>: a typical form to manage data in a business entity
</p><p>The whole form only needs very few lines of business code to get the data from the server and save it into some dependency properties. <strong>All the data transfer and validation between the controls and the application code behind is entirely managed by XAML tags</strong>.
</p><p>The code snippets below shows the form left and right panels code behind which is limited to few dependency properties and the commands to act on them:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image002a_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image002a_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image002a_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image002a_thumb.png" alt="" border="0"/></a>
	</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003a_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003a_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003a_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003a_thumb.png" alt="" border="0"/></a>
	</p><p><strong>Figure 2</strong>: The forms code-behind only contains business data and commands; Rendering and validation is specified at XAML level.
</p><h2>Reason n° 3: User Interface and Business Logic may be separated easily and clearly
</h2><p>As illustrated in reason n° 2, WPF allows keeping a strong separation between the business data and the user interface controls. The data transfer between the business data and the user controls is carried over by WPF data binding so, the business code never needs to access the application user interface controls and their properties explicitly.
</p><p>As a result, the entire business logic is independent from the controls used to render the data. So, changing the application user interface is easier and, most often, doesn't affect the application code.
</p><p>Old Windows Forms and other te chnologies used many "custom" frameworks to obtain such separation between the User interface logic and the Business logic, often, at the cost of some overhead for developers.
</p><p>WPF provides this separation by design and doesn't require any extra code to get it!
</p><h2>Reason n° 4: Routed Commands allow easy command management with automatic support for enabling controls
</h2><p>WPF provides a powerful, built-in, infrastructure for defining commands and attaching them to UI elements. The developer <strong>defines typed commands</strong>, <strong>associates them to user interface elements</strong> and <strong>provides command implementations</strong> within code. Any command, when started from a UI element, is <strong>routed</strong> through the parent elements chain until a command implementation is found and executed. <strong>This allows decoupling the UI elements that generate commands from the command implementations</strong>. 
</p><p>The XAML snippet below shows 2 buttons associated to commands by means of the command attribute:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003b_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003b_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003b_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003b_thumb.png" alt="" border="0"/></a>
	</p><p>The (Search) command implementation and its enabling condition can be defined in the code behind with a <strong>CanExecute</strong>() and a <strong>Command</strong>() methods, as shown below:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003c_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003c_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003c_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image003c_thumb.png" alt="" border="0"/></a>
	</p><p>The <strong>WPF Command Manager routes commands and verifies their conditions; all UI elements associated to commands that cannot be executed are disabled automatically</strong>.
</p><p> 
 </p><p>The image below shows the two buttons run time: the Command Manager is disabling the Search Button as Search command cannot be executed.
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image004_4.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image004_4.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image004_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image004_thumb_1.png" alt="" border="0"/></a>
	</p><p><strong>Figure 3</strong>: the command manager disables buttons and other UI elements based on Command CanExecute() handlers
</p><h2>Reason n° 5: XAML dynamic loading allows changing the User interface and the application behavior depending on the user profile or user rights.
</h2><p>A very common requirement for business applications Is that the menus and the functions available may depend on contextual information such as the user profile or the user rights. Traditional application architectures usually address such requirement with complex configuration schemas and lots of code to load the required UI elements, at run time.
</p><p>WPF allows loading entire XAML sections (e.g. contextual menus) dynamically and merging them into the application User Interface with very few instructions. The loaded XAML is automatically bound to the business code by the command routing.
</p><p>The code snippet below shows how to load dynamically a ribbon control from a resource file:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_2.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb.png" alt="" border="0"/></a>
	</p><p>So, configuration for dynamic menus may now be defined directly with XAML and the code for loading them may be significantly simpler.
</p><h2>Reason n° 6: client side and server side validations are very easy and powerful with Data Binding Validation Architecture and Routed Events.
</h2><p>When defining a data binding, few additional attributes allow the developer to specify validations to ensure the correctness of the data transferred from the control to the underlining properties. 
</p><p>The code snippet below shows a textbox, bound to a "company object" property with two validation rules for the data transferred.
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_4.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_4.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_1.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_1.png" alt="" border="0"/></a>
	</p><p>By default, WPF gives evidence to validation failures adding a red border to the control that owns the binding, as shown below:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_6.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_6.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_2.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_2.png" alt="" border="0"/></a>
	</p><p><strong>Figure 4</strong>: validation failures are rendered as a red border around the failing control
</p><p>Styles and routed events may change the visual feedback of failed validations in a way completely transparent to the developer: with, the same XAML code you may generate an entirely different visual feedback for validations, as shown below:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_8.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_8.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_3.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_3.png" alt="" border="0"/></a>
	</p><p><strong>Figure 5</strong>: Styles and routed events allows changing the visual feedback of validation failures without affecting the business code
</p><h2>Reason n° 7: The application is more flexible and easy to maintain.
</h2><p>Reasons n° 2, 3 and 4 generally <strong>ensure the business code to be simpler and reduced</strong>. Changes to the business logic are easier to maintain as <strong>the business code is isolated </strong>and It is not complicated by the rendering logic. Changes to the rendering logic are easy as they usually involve only changes to the XAML without affecting the application code.
</p><p>Reasons such as n° 4, 5 and 6 allows <strong>having less code also for the application infrastructure</strong> (e.g. dynamic menus, command management, validation, authorization etc).
</p><h2>Reason n° 8: XAML, styling and control templating allow rendering complex data very flexibly.
</h2><p>The rendering reflects data changes very efficiently, the connection between the data and the user interface can be read only or read write. Most often, changing the rendering of data is very easy and doesn't affect the application code.
</p><p>In the example below you can see a dialog box showing information about an application exception, for the Help Desk:
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_10.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_10.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_4.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_4.png" alt="" border="0"/></a>
	</p><p><strong>Figure 6</strong>: a sample form to render information about an exception
</p><p>Another Tab of the same dialog shows exactly the same data for the application developer
</p><p><a href="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_12.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_12.png"><img src="https://msdnshared.blob.core.windows.net/media/TNBlogsFS/BlogFileStorage/blogs_msdn/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_5.png" original-url="https://blogs.msdn.com/blogfiles/darioa/WindowsLiveWriter/KeyreasonswhyuseWPFonaBusinessApplicatio_15147/image_thumb_5.png" alt="" border="0"/></a>
	</p><p><strong>Figure 7</strong>: the same data may be rendered in a radically different way changing the XAML only.
</p><p>The business data behind the XAML is the same for the two views: the xaml makes the difference rendering the same data in different ways.
</p><h2>Reason n° 9: WPF works with device independent metrics and allows creating interfaces that adapt to different screen resolutions
</h2><p>Many panels such as Grid, DockPanel, StackPanel, etc allow adapting the controls sizes and layout to the various screen resolutions that may be available.
</p><p>Scaling and rendering to XPS may help you creating your support for printing.
</p><h2>Conclusions
</h2><p>WPF may change significantly the way of developing your applications.
</p><p>Less and easier code is required to write your traditional applications and addressing more complex scenarios is now easier!
</p><h3>Additional References
</h3><p><a href="https://www.thejoyofcode.com/10_reasons_you_should_consider_WPF_for_your_next_desktop_application.aspx">https://www.thejoyofcode.com/10_reasons_you_should_consider_WPF_for_your_next_desktop_application.aspx</a>
	</p><p>Technorati Tag: <a href="https://technorati.com/tags/Framework%203">Framework 3</a>,<a href="https://technorati.com/tags/Windows%20Presentation%20Foundation">Windows Presentation Foundation</a>,<a href="https://technorati.com/tags/WPF">WPF</a>
	</p>]]></content:encoded>
    </item>
    <item>
      <title>Micro Framework TripComputer Sample</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/micro-framework-tripcomputer-sample</link>
      <pubDate>Wed, 25 Apr 2007 15:23:00 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/04/25/micro-framework-tripcomputer-sample/</guid>
      <description><![CDATA[Micro Framework introduces a new approach to embedded development. 
The following key points:...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;" size="3"><em><b>Micro Framework</b></em><span style="font-family: Calibri;" face="Calibri"> introduces a new approach to embedded development. </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">The following key points: </span></span></p>
<ul>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Minimal hardware requirements </span></span></li>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Strong runtime support </span></span></li>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Easy and intuitive development model </span></span></li>
<li><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">An extensible emulation environment </span></span></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Make it<em><b> </b></em>easy to address application development for simple devices used in consumer electronic and industrial automation. </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Additional resources about Micro Framework are: </span></span></p>
<ul>
<li><a href="https://download.microsoft.com/download/3/1/9/319f7469-70bd-4e7c-a6cc-e5ad96939af4/net_micro_framework_whitepaper_v_1.0.doc"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Microframework WhitePaper</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></li>
<li><a href="https://msevents.microsoft.com/cui/WebCastEventDetails.aspx?culture=en-US&amp;EventID=1032314669&amp;CountryCode=us"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">MSDN Webcast: An Introduction to the .NET Micro Framework</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></li>
<li><a href="https://msdn2.microsoft.com/en-us/embedded/bb267253.aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Micro Framework msdn web site</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">. </span></span></li>
<li><a href="https://www.dotnetmicroframework.com/"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Micro Framework web site</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></li>
<li><a href="https://blogs.msdn.com/aldenl/default.aspx"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Alden Linn blog</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></li>
<li><a href="https://www.microsoft.com/communities/newsgroups/list/en-us/default.aspx?dg=microsoft.public.dotnet.framework.microframework&amp;cat=en_us_C4FAF74A-95F6-CD60-F2E1-ED8EDB03324B&amp;lang=en&amp;cr=us"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Micro Framework newsgroup</span></a><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></li>
<li><a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=32f5df20-6c95-4fe8-a76c-0ed56a839ad2&amp;DisplayLang=en"><span style="color: #0000ff; font-family: Calibri; font-size: small;" face="Calibri" size="3" color="#0000ff">Micro Framework SDK Download page</span></a></li>
</ul>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Attached, I propose the <em><b>TripComputer Sample</b></em> and <em><b>SampleEmulator </b></em>applications I used in a recent Webcast. </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">The Trip Computer sample is a very simple application that shows the structure of a Micro Framework application. </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">SampleEmulator application shows a simple customization where I added a GPIO button to the default emulator to better simulate the real tripcomputer. </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">The following figure shows the tripcomputer application run with the default emulator and with the customized version of the emulator: </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">&nbsp;&nbsp;&nbsp;<span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0602.Figure%201%20sample%20emulator.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0602.Figure-1-sample-emulator.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0602.Figure%201%20sample%20emulator.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0602.Figure-1-sample-emulator.png" width="370" height="654" /></a></span></span></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The application starts on the <em><b>static main()</b></em> method of a class deriving from <em><b>Microsoft.SPOT.Application</b></em>. </span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7360.Figure%202%20class%20program.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7360.Figure-2-class-program.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/7360.Figure%202%20class%20program.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/7360.Figure-2-class-program.png" /></a>&nbsp;</span><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"> </span></span></p>
<p><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">Static main method creates an instance of the TripComputer Window and starts a Dispatch loop on it. </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">Class TripComputerWindow derives from <em><b>Microsoft.SPOT.Presentation.Window</b></em> and aggregates some panels and textboxes using the <em><b>Windows Presentation Foundation (WPF)</b></em> object model. </span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"></span><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6232.Figure%203%20TripComputerWindow.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6232.Figure-3-TripComputerWindow.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/6232.Figure%203%20TripComputerWindow.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/6232.Figure-3-TripComputerWindow.png" /></a>&nbsp; </span></span></p>
<p><span style="font-size: small;" size="3"><em><b>Load()</b></em><span style="font-family: Calibri;" face="Calibri"> Method shows the code to start a timer for updating the clock on the bottom right angle of the trip computer. </span></span></p>
<p><span style="font-family: Calibri; font-size: small;" face="Calibri" size="3"></span><span style="font-family: Calibri;" face="Calibri"><span style="font-size: small;" size="3">&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5773.Figure%204%20Load.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5773.Figure-4-Load.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5773.Figure%204%20Load.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5773.Figure-4-Load.png" /></a> </span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The TripComputer application shows some features unique to Micro Framework WPF graphic engine like the <em><b>linear gradient</b></em> brush on the background, the <em><b>controls layout</b></em> by means of vertical and horizontal stack panels and the interception of the ButtonUpEvent<em><b> routed event</b></em> at the main window level. </span></span></p>
<p>&nbsp;In summary, developing embedded applications with Micro Framework is easy and intuitive and relays on the same development model of other .Net applications</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/02/27/53/64/Micro%20Framework%20Samples.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-02-27-53-64/Micro-Framework-Samples.zip">Micro Framework Samples.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>WCF Samples</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/wcf-samples</link>
      <pubDate>Sun, 25 Mar 2007 13:22:00 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/03/25/wcf-samples/</guid>
      <description><![CDATA[Windows Communication Foundation (WCF) the new API set and runtime for message based...]]></description>
      <content:encoded><![CDATA[<p><strong><em>Windows Communication Foundation (WCF)</em></strong> the new API set and runtime for message based communication.</p>
<ul>
<li>
<div><strong><em>WCF</em></strong> <strong><em>replaces old web services</em></strong> as WCF Services support HTTP/Soap based communication.</div>
<p>In particular, WCF now supports WS* standards for secure, reliable communication etc.</p>
<p>Also, WCF services can be hosted by IIS Services, WAS or they can be self hosted into a custom application.</p>
</li>
<li>
<div><strong><em>WCF replaces old .Net-Remoting</em></strong> communication as WCF Services support binary communication above TCP/IP and named pipes.</div>
<p>Other channels such as MSMQ and peer messaging channel are supported.</p>
<p>Also, a flexible extensibility model allows adding new custom protocols and channels.</p>
</li>
<li><strong><em>WCF replaces enterprise services</em></strong> as WCF Services support transactions by means of OleTx and WS-Transactions etc.</li>
</ul>
<p>&nbsp;</p>
<p>This article contains the following samples:</p>
<ul>
<li><strong><em>SelfHosting sample</em></strong>: WPF calculator client calling a calculator service by SelfHosting.</li>
<li><strong><em>MessageInterceptor Sample</em></strong>: IClientMessageInspector, IParameterInspector and IDispatchMessageInspector to perform message and parameter interception.</li>
</ul>
<p>&nbsp;</p>
<h1>SelfHosting sample</h1>
<p>Selfhosting sample shows a WPF windows application that implements a client for the calculator service.</p>
<p>The calculator client performs the calculations calling the CalculatorService component.</p>
<p>The following diagram shows the CalculatorClient and CalculatorService components.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1588.Figure1%20Calculator.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1588.Figure1-Calculator.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1588.Figure1%20Calculator.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1588.Figure1-Calculator.png" width="390" height="299" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0333.Figure2%20classes.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0333.Figure2-classes.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0333.Figure2%20classes.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0333.Figure2-classes.png" width="190" height="286" /></a></p>
<p>&nbsp;</p>
<p>The CalculatorService is SelfHosted into the client application by means of the following code:</p>
<p><span style="color: blue; font-family: Lucida Console; font-size: 8pt;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5557.Figure3%20StartHost.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5557.Figure3-StartHost.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/5557.Figure3%20StartHost.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/5557.Figure3-StartHost.png" /></a>&nbsp;</span></p>
<p>&nbsp;</p>
<p>The service configuration below shows that at startup 2 endpoint listeners are loaded do that the service can be connected by means of TCP/IP or by named pipes:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0511.Figure4%20Config.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0511.Figure4-Config.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0511.Figure4%20Config.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0511.Figure4-Config.png" /></a></p>
<p>&nbsp;</p>
<p>With the following configuration the calculator clients connects the selfhosted service by means of the tcp/ip endpoint:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3324.Figure5%20clientconfig.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3324.Figure5-clientconfig.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3324.Figure5%20clientconfig.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3324.Figure5-clientconfig.png" /></a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<h1>MessageInterceptor Sample</h1>
<p>MessageInterceptor sample shows using the WCF extensibility model to intercept client application calls at class and method level.</p>
<p>This can be done creating a <strong><em>WCF Behaviour</em></strong> class for the service and attaching it to the service by means of the configuration.</p>
<p>&nbsp;</p>
<p>Client Interception is performed by means of <span style="font-family: Lucida Console; font-size: 8pt;"><span style="color: #2b91af;">IClientMessageInspector</span>, <span style="color: #2b91af;">IParameterInspector </span></span>interfaces and Service interception is performed <span style="font-family: Lucida Console; font-size: 8pt;"><span style="color: #2b91af;">IDispatchMessageInspector</span>, <span style="color: #2b91af;">IParameterInspector. </span></span></p>
<p>&nbsp;</p>
<p>The MessageInterceptorClass shown below implements all the interfaces to provide CalculatorService interception at the client and dispatcher side.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3513.Figure6%20MessageInterceptorClass.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3513.Figure6-MessageInterceptorClass.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/3513.Figure6%20MessageInterceptorClass.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/3513.Figure6-MessageInterceptorClass.png" width="231" height="305" /></a></p>
<p>&nbsp;</p>
<p>The message interceptor is installed into the client or dispatcher side by means if a Behaviour.</p>
<p>MessageInterceptorBehaviour class below shows how to install the interceptor class at the client side (<strong><em>ApplyClientBehaviour()</em></strong>) or dispatcher side (<strong><em>ApplyDispatchBehaviour()</em></strong>).</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1882.Figure8%20MessageInterceptorBehaviour.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1882.Figure8-MessageInterceptorBehaviour.png"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/1882.Figure8%20MessageInterceptorBehaviour.png" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/1882.Figure8-MessageInterceptorBehaviour.png" width="243" height="326" /></a></p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/01/94/79/10/WCF%20Samples.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-94-79-10/WCF-Samples.zip">WCF Samples.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>"Certified for Vista" Logo Samples</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/certified-for-vista-logo-samples</link>
      <pubDate>Thu, 11 Jan 2007 09:07:00 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/01/11/certified-for-vista-logo-samples/</guid>
      <description><![CDATA[The following samples show the most common tasks you may need to perform on your application to get...]]></description>
      <content:encoded><![CDATA[<P>The following samples show the most common tasks you may need to perform on your application to get the "Certified for Vista Logo". </P>
<P>In particular, CertifiedforVistaSamples.zip include: </P>
<UL>
<LI><STRONG><EM>Manifestsample</EM></STRONG>: shows how to apply a manifest to your .Net application resources with a postbuild rule. </LI>
<LI><STRONG><EM>ManifestsampleVB6</EM></STRONG>: shows how to apply a manifest to an existing application with MT utility. </LI>
<LI>
<DIV><STRONG><EM>Signaturesample</EM></STRONG>: shows how to apply a certificate to your application resources with a postbuild rule. </DIV>
<P>The sample also shows how to generate a certificate with makecert utility. </P></LI></UL>
<P>The zip also include: </P>
<UL>
<LI><STRONG><EM>RegistrySample</EM></STRONG>: a sample application that allow writing any registry key and check whether the key is a Windows Resource Protected key. </LI></UL>
<P>For more information on Windows Vista Logo Programs see: </P>
<UL>
<LI><A href="https://blogs.msdn.com/darioa/archive/2006/11/29/faq-on-windows-vista-compatibility-and-certification.aspx" mce_href="https://blogs.msdn.com/darioa/archive/2006/11/29/faq-on-windows-vista-compatibility-and-certification.aspx">Frequently asked questions on Windows Vista compatibility and Certification Logos</A> </LI>
<LI><A href="https://www.microsoft.com/windowsvista/" mce_href="https://www.microsoft.com/windowsvista/">https://www.microsoft.com/windowsvista/</A> </LI></UL>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/01/45/07/20/CertifiedForVistaSamples.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-01-45-07-20/CertifiedForVistaSamples.zip">CertifiedForVistaSamples.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Steps to prepare lab machines with Windows Vista AIK</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/steps-to-prepare-lab-machines-with-windows-vista-aik</link>
      <pubDate>Wed, 10 Jan 2007 13:02:52 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/01/10/steps-to-prepare-lab-machines-with-windows-vista-aik/</guid>
      <description><![CDATA[The steps to create a lab installation are easy with Windows Vista AIK. With a clear idea of what...]]></description>
      <content:encoded><![CDATA[<p>The steps to create a lab installation are easy with Windows Vista AIK. With a clear idea of what you need to install on the machines and the requirements described below, a couple of days may be enough to have everything in place.
</p><p>Also, only a single image may be applied to different machines.
</p><p>The steplist described below is taken from <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=993c567d-f12c-4676-917f-05d9de73ada4&amp;DisplayLang=en">Getting Started with the Windows Automated Installation Kit</a>.
</p><h2>Requirements
</h2><ul><li><strong><em>Vista DVD</em></strong>: a DVD with Windows Vista.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>WAIK</em></strong>: Windows Vista Automated Installation Kit (get the download <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=c7d4bc6d-15f3-4284-9123-679830d629f2&amp;DisplayLang=en">here</a>).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>A USB Key</em></strong>: this is needed to contain the answers file for the installation (a little key should be ok).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Blank CD/DVD RW</em></strong>: this is needed to boot lab machines at installation time.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Master PC</em></strong>:  a Lab machine to setup the Vista master installation.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Technician PC</em></strong>: a pc with a DVD ROM Drive (RW capable), Windows AIK, and the tools described below.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Network Connectivity</em></strong>: this is needed to store the OS Image for lab machines (NB The LAB machine image file will contain the lab machine system drive, so it can possibly be very large!!).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>CDBurn/Dvdburn</em></strong> utility: this tool allows burning a DVD from a ISO Image (<a href="https://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;displaylang=en">Windows Server 2003 Resource Kit Tools</a>).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li></ul><p>The following steps can be applied to take the image of a single disk lab machine. 
</p><h2>Step 1: create a bootable Windows PE RAM CD/DVD 
</h2><ul><li>Follow instructions in "<a href="https://blogs.msdn.com/darioa/archive/2007/01/10/steps-to-create-a-bootable-windows-pe-ram-cd-dvd.aspx">Steps to create a bootable Windows PE RAM CD/DVD</a>"
</li></ul><h2>Step 2: setup the master PC
</h2><ol><li>Start the master PC with Vista DVD and setup Vista.
</li><li>Configure Vista and setup all the software you need to the master PC.
</li></ol><ul><li>run the "<strong><em>disk clean up wizard</em></strong>" from the disk manager to reduce as much as possible the image size.
</li><li>Run <strong><em>sysprep.exe /oobe /generalize /shutdown</em></strong> from folder "<strong><em>c:\windows\system32\sysprep</em></strong>"
</li></ul><h2>Step 3: take an image of the master PC
</h2><ul><li>Boot the Master PC with the Windows PE RAM CD.
</li><li><strong><em>type d:</em></strong> from "command prompt" to change the current drive from the RAM DRIVE to the DVD.
</li><li>Type <strong><em>imagex /compress fast /capture c: c:\ image.wim "Vista Lab Install" /Verify
</em></strong></li><li>Save the image (<strong><em>image.wim)</em></strong> onto a reachable network share (es. <strong><em>\\master\labimage</em></strong>).
</li></ul><h2>Step 4: apply the Image to Lab PCs
</h2><ul><li>Boot the Master PC with the Windows PE RAM CD.
</li><li><div>Create 2 partitions on the pc with the following diskpart script
</div><p><strong><em>diskpart /s diskpartcleanscript.txt
</em></strong></p><p>
 </p><p>Where diskpartcleanscript.txt contains the following text:
</p><p>select disk 0
</p><p>clean
</p><p>create partition primary SIZE=60000
</p><p>select partition 1
</p><p>active
</p><p>format quick
</p><p>assign letter=<strong><em>C</em></strong>
			</p><p>create partition primary
</p><p>select partition 2
</p><p>format quick
</p><p>assign letter=<strong><em>Y</em></strong>
			</p><p>exit
</p><p>
 </p></li><li><div>Download Vista Image (<strong><em>image.wim</em></strong>) on drive "<strong><em>y:</em></strong>"
</div><p>use the following script:
</p><p>net use \\master\labimage /User:master\lab *****
</p><p>robocopy \\master\labimage . install.wim
</p><p>
 </p></li><li><div>Run imagex /apply of the image to the first partition
</div><p>imagex /apply y:\labimage\install.wim 1 c:
</p></li></ul><p>
 </p>]]></content:encoded>
    </item>
    <item>
      <title>Steps to create a bootable Windows PE RAM CD/DVD</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/steps-to-create-a-bootable-windows-pe-ram-cddvd</link>
      <pubDate>Wed, 10 Jan 2007 13:01:14 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/01/10/steps-to-create-a-bootable-windows-pe-ram-cddvd/</guid>
      <description><![CDATA[The following article shows how to create a bootable WinPE disk with  Windows Vista Automated...]]></description>
      <content:encoded><![CDATA[<p>The following article shows how to create a bootable WinPE disk with <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=c7d4bc6d-15f3-4284-9123-679830d629f2&amp;DisplayLang=en"> Windows Vista Automated Installation Kit (WAIK)</a>.
</p><h2>Requirements
</h2><ul><li><strong><em>WAIK</em></strong>: Windows Vista Automated Installation Kit (get the download <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=c7d4bc6d-15f3-4284-9123-679830d629f2&amp;DisplayLang=en">here</a>).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>CDBurn/Dvdburn</em></strong> utility: this tool allows burning a DVD from a ISO Image (<a href="https://www.microsoft.com/downloads/details.aspx?familyid=9d467a69-57ff-4ae7-96ee-b18c4790cffd&amp;displaylang=en">Windows Server 2003 Resource Kit Tools</a>).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Technician PC</em></strong>: a pc with a CD/DVD ROM Drive (RW capable) with Windows AIK installed on it.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>A blank CD or DVD</em></strong>.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li></ul><h2>Steps to create the bootable disk
</h2><ul><li><div>Run the following commands from <strong><em>"Windows PE Tools Command Prompt"</em></strong>:
</div><ul><li><strong><em>copype.cmd x86 c:\winpe_x86
</em></strong></li></ul></li><li><div>(optional) Copy imagex tool and an imagex exclusion list:<strong><em>
					</em></strong></div><ul><li>Run<strong><em> copy "C:\Program Files\Windows AIK\Tools\x86\imagex.exe" "C:\winpe_x86\ISO"
</em></strong></li><li><div>create a <strong><em>wimscript.ini</em></strong> file to <strong><em>"C:\winpe_x86\ISO"</em></strong> with the following exclusions<strong><em>
							</em></strong></div><p>[ExclusionList]
</p><p>ntfs.log
</p><p>hiberfil.sys
</p><p>pagefile.sys
</p><p>"System Volume Information"
</p><p>RECYCLER
</p><p>Windows\CSC
</p><p> [CompressionExclusionList]
</p><p>*.mp3
</p><p>*.zip
</p><p>*.cab
</p><p>\WINDOWS\inf\*.pnf
</p></li></ul></li><li><div>Create the iso for the bootable disk<strong><em>:</em></strong>
			</div><ul><li><strong><em>oscdimg -n -bC:\winpe_x86\etfsboot.com C:\winpe_x86\ISO C:\winpe_x86\winpe_x86.iso
</em></strong></li></ul></li><li><div>Burn the iso file to a dvd or cdrom
</div><ul><li> "dvdburn d: C:\<em>winpe_x86\winpe_x86.iso" to burn the iso file to a DVD.
</em></li><li><em>"cdburn d: C:\win</em>pe_x86\winpe_x86.iso" to burn the iso file to a CD.
</li></ul></li></ul><p>Note that step 2 is not required and is only useful to have imagex tool on the bootable disk.
</p><p>You may add any other tools or batches to your bootable disk in a similar way.
</p>]]></content:encoded>
    </item>
    <item>
      <title>Steps to Create an Unattended Setup for Windows Vista</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/steps-to-create-an-unattended-setup-for-windows-vista</link>
      <pubDate>Wed, 10 Jan 2007 12:57:55 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2007/01/10/steps-to-create-an-unattended-setup-for-windows-vista/</guid>
      <description><![CDATA[The following article shows how to create an automated setup per windows Vista using Windows Vista...]]></description>
      <content:encoded><![CDATA[<p>The following article shows how to create an automated setup per windows <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=c7d4bc6d-15f3-4284-9123-679830d629f2&amp;DisplayLang=en">Vista using Windows Vista Automated Installation Kit (WAIK)</a>.
</p><h2>Requirements
</h2><ul><li><strong><em>Vista DVD</em></strong>: a DVD with Windows Vista.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>WAIK</em></strong>: Windows Vista Automated Installation Kit (get the download <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=c7d4bc6d-15f3-4284-9123-679830d629f2&amp;DisplayLang=en">here</a>).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>A USB Key</em></strong>: this is needed to contain the answers file for the installation (a key with very little space is ok).<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><strong><em>Technician PC</em></strong>: a pc with a DVD ROM Drive (RW capable) with Windows AIK installed on it.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li></ul><h2>Steps to create the answer file
</h2><ul><li>Copy <strong><em>Install.Wim</em></strong> (2GB) from <strong><em>vista DVD</em></strong> to the <strong><em>technician PC</em></strong>.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li>Start "<strong><em>Microsoft Windows AIK -</em></strong>
			<strong><em>Windows System Image Manager</em></strong>".<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><div>Select the <strong><em>Install.Wim</em></strong> file from the "<strong><em>File - Select Windows Image</em></strong>" menu.<span style="font-family:Times New Roman; font-size:12pt">
				</span></div><p>NB. The command will let you choose a Vista version (es. Ultimate) and create a catalog file.
</p></li><li>Create a new answer file with "<strong><em>File - New Answer File</em></strong>" menu.<span style="font-family:Times New Roman; font-size:12pt">
			</span></li><li><div>From the "<strong><em>Windows Image</em></strong>" pane add  the following settings to the Answer File:
</div><ul><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Setup\DiskConfiguration\Disk\CreatePartitions\CreatePartition (1 windowsPE component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Setup\DiskConfiguration\Disk\ModifyPartitions\ModifyPartition (1 windowsPE component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Setup\ImageInstall\OSImage\InstallTo (1 windowsPE component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Setup\UserData (1 windowsPE component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Shell-Setup\OOBE (7 oobeSystem component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-Shell-Setup\AutoLogon     (7 oobeSystem component).
</span></li><li><span style="font-family:Times New Roman; font-size:12pt">Microsoft-Windows-International-Core-WinPE  (1 windowsPE component).
</span></li></ul></li><li><div>Into the  the "<strong><em>Answers File</em></strong>" pane set the  following settings:
</div><ul><li><div>Microsoft-Windows-Setup  (1 windowsPE component).
</div><ul><li>Microsoft-Windows-Setup\DiskConfiguration    WillShowUI = OnError
</li><li>Microsoft-Windows-Setup\DiskConfiguration\Disk    DiskID = 0
</li><li>WillWipeDisk = true
</li></ul></li><li><div>Microsoft-Windows-Setup\DiskConfiguration\Disk\CreatePartitions\CreatePartition
</div><ul><li>Order = 1
</li><li>Extend = true (this formats the entire disk)
</li><li>Type = Primary
</li></ul></li><li><div>Microsoft-Windows-Setup\DiskConfiguration\Disk\ModifyPartitions\ModifyPartition
</div><ul><li>Active = true
</li><li>Format = NTFS
</li><li>Label = OS_Install
</li><li>Letter = C
</li><li>Order = 1
</li><li>PartitionID = 1
</li></ul></li><li>Microsoft-Windows-Setup\ImageInstall\OSImage\    WillShowUI = OnError
</li><li><div>Microsoft-Windows-Setup\ImageInstall\OSImage\InstallTo    DiskID = 0
</div><ul><li>PartitionID = 1
</li></ul></li><li>Microsoft-Windows-Setup\UserData    AcceptEula = true
</li><li><div>Microsoft-Windows-Setup\UserData\ProductKey    Key = &lt;product key&gt;
</div><ul><li>WillShowUI = OnError
</li></ul></li><li><div>Microsoft-Windows-Shell-Setup\OOBE    HideEULAPage = true
</div><ul><li>ProtectYourPC = 3
</li><li>SkipMachineOOBE = true
</li><li>SkipUserOOBE = true
</li></ul></li><li><div>Microsoft-Windows-International-Core-WinPE    InputLocale = &lt;Input Locale&gt; (es 'it-IT')
</div><ul><li>SystemLocale = &lt;System Locale&gt;  (es 'it-IT')
</li><li>UILanguage = &lt;UI Language&gt;  (es 'en-US')
</li><li>UserLocale = &lt;User Locale&gt; (es 'it-IT')
</li></ul></li><li>Microsoft-Windows-International-Core-WinPE\SetupUILanguage    UILanguage = &lt;UI Language&gt;
</li><li><div>Microsoft-Windows-Shell-Setup\AutoLogon    Enabled = true
</div><ul><li>LogonCount = 5
</li><li>Username = Administrator
</li></ul></li><li>Microsoft-Windows-Shell-Setup\AutoLogon\Password    &lt;strongpassword&gt;
</li></ul></li><li>Save the <strong><em>Answer File</em></strong> into the <strong><em>USB Key</em></strong>.
</li></ul><p>You are now ready to run your Windows Vista unattended installation with the following command:
</p><p><strong><em> setup /unattend: answerfilename
</em></strong></p><p>Note that Windows Vista setup program automatically looks for answer files named "<strong><em>AutoUnattend.xml</em></strong>" in several different locations including a previously cached answer file and an answer file at the root of a drive.
</p>]]></content:encoded>
    </item>
    <item>
      <title>Frequently asked questions on Windows Vista compatibility and Certification Logos</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/frequently-asked-questions-on-windows-vista-compatibility-and-certification-logos</link>
      <pubDate>Wed, 29 Nov 2006 08:06:02 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2006/11/29/frequently-asked-questions-on-windows-vista-compatibility-and-certification-logos/</guid>
      <description><![CDATA[The following article proposes some Frequently Asked Questions and Answers about Windows Vista...]]></description>
      <content:encoded><![CDATA[<p>The following article proposes some Frequently Asked Questions and Answers about Windows Vista Compatibility and Vista Certification Logos. 
</p><p>I gathered information below from compatibility and logo draft documents and from internet resources that are subject to change. 
</p><p>Official and detailed information about Vista compatibility and Compatibility Logo Programs is available at <a href="https://www.microsoft.com/windowsvista/">https://www.microsoft.com/windowsvista/</a> and <a href="https://microsoft.mrmpslc.com/InnovateOnWindowsVista/">https://microsoft.mrmpslc.com/InnovateOnWindowsVista/</a><span style="color:#1f497d">. </span>
	</p><p>You can access the latest version of this document <a href="https://blogs.msdn.com/darioa/archive/2006/11/29/faq-on-windows-vista-compatibility-and-certification.aspx">here</a>. 
</p><p>     
 </p><h1>FAQ on Windows Vista Certification Logos 
</h1><p><strong><em>Question</em></strong>: How does "<strong><em>Certified for Vista</em></strong>" differ from "<strong><em>Works with Vista</em></strong>" logo certification? 
</p><p><strong>Answer</strong>: "<strong><em>Certified for Vista</em></strong>" applications must conform to "<a href="https://download.microsoft.com/download/8/e/4/8e4c929d-679a-4238-8c21-2dcc8ed1f35c/Windows%20Vista%20Software%20Logo%20Spec%201.1.doc"><span style="color:blue; text-decoration:underline"><em>Windows Vista Software Logo Spec 1.1</em></span></a>" and "<a href="https://download.microsoft.com/download/a/5/d/a5d3d02a-fd03-466f-9ba8-97f5e7a90a98/CertifiedforWindowsVistaProgramTestCases.doc"><span style="color:blue; text-decoration:underline"><em>Certified for Program TestCases</em></span></a>" and must be submitted for verification to get the logo. "<strong><em>Works with Vista</em></strong>" is a self-asserted certification where companies just verify compatibility and pledge to support on Vista. "<strong><em>Works with Vista</em></strong>" may be obtained with no charge, apart the cost of the Verisign Certificate needed to create an account on <a href="https://winqual.microsoft.com/Default.aspx?ReturnUrl=%2fmember%2fSoftwareLogo%2fDefault.aspx">winqal</a> site. 
</p><p> 
 </p><p><strong><em>Question</em></strong>: Does "<strong><em>Certified for Vista</em></strong>" logo certification include requirements about accessibility, application graphic layout and rendering behavior (ex. icon sizes, toolbars etc) as it did on the Certified for windows XP logo certifications? 
</p><p><strong>Answer</strong>: No, most vista logo requirements only include Install/Uninstall, Reliability and Security Requirements (see. "<a href="https://download.microsoft.com/download/8/e/4/8e4c929d-679a-4238-8c21-2dcc8ed1f35c/Windows%20Vista%20Software%20Logo%20Spec%201.1.doc"><span style="color:blue; text-decoration:underline"><em>Windows Vista Software Logo Spec 1.1</em></span></a>" and "<a href="https://download.microsoft.com/download/a/5/d/a5d3d02a-fd03-466f-9ba8-97f5e7a90a98/CertifiedforWindowsVistaProgramTestCases.doc"><span style="color:blue; text-decoration:underline"><em>Certified for Program TestCases</em></span></a>"). 
</p><p> 
 </p><p><strong><em>Question</em></strong>: When are <strong><em>Manifest</em></strong> and <strong><em>Digital signature</em></strong> required by Vista Logos? 
</p><p><strong><em>Answer</em></strong>: Windows Vista 64-bit editions always require the "Digital Signature" for 64-Bit drivers 
</p><ul><li>"<strong><em>Certified for vista</em></strong>" software logo requires that all exe and drivers be signed with an authenticode certificate. 
</li><li>"<strong><em>Certified for vista</em></strong>" software logo also requires that all exe and installers contain an embedded manifest with the declaration of appropriate UAC Execution level. 
</li><li>"<strong><em>Works with vista</em></strong>" software logo doesn't require that exe and installers contain an embedded manifests or signature. 
</li></ul><p>An authenticode certificate to comply this requirement may be acquired from a vendor like Verisign or it may be generated by means of a custom certificate authority (ex. The certificate authority included in Windows 2003). 
</p><p>     
 </p><p><strong><em>Question</em></strong>: what happens if an application uses third party components or drivers? 
</p><p><strong><em>Answer</em></strong>: if the application uses a third party component that is not signed the ISV can apply for a waiver on that particular file. 
</p><p>If an application cannot sign a <span style="text-decoration:underline">kernel mode driver</span> they must contact <a href="mailto:swlogo@microsoft.com">swlogo@microsoft.com</a> and detail exactly why their driver cannot be signed. 
</p><p>An application can certify without printing functionality if the printing functionality is not part of its primary functionality. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: what happens if an application uses third party runtime that is not singed? 
</p><p><strong><em>Answer</em></strong>: if the application uses a third party runtime that is not signed the ISV can apply for a waiver on that particular file. 
</p><p>This applies, for example, to VB6 applications as vb6 runtime files are not signed. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Do Vista Logo requirements allow including "<strong><em>system components</em></strong>
		<strong><em>merge modules</em></strong>" into custom application setup programs? 
</p><p><strong><em>Answer</em></strong>: Yes, as long as the merge modules for the system components are those published by microsoft. 
</p><p>Again, these solutions to these problems can be work out on a case by case. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Do Vista Logos require "<strong><em>Uninstall Programs</em></strong>" to delete application files and shortcuts from existing user profiles? 
</p><p><strong><em>Answer</em></strong>: logo verification steps require that appropriate clean up is performed on <strong><em>setup failure</em></strong>. 
</p><p>Use of the application may create files and folders on the user profile that are not required to be removed. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Do Vista Logos require "<strong><em>Uninstall Programs</em></strong>" to remove database server and data files? 
</p><p><strong><em>Answer</em></strong>: Roll back requirement <strong><em>refers to a</em></strong>
		<strong><em>failed install</em></strong>, not a standard install. The requirement is that if the msi installer fails to successfully install it must rollback and return the system to its previous state before the install began. For uninstallation which is not part of this test case, data can be left behind. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Can <strong><em>VB6</em></strong> and <strong><em>older Visual Studio applications</em></strong> apply for Windows Vista Logo certification? 
</p><p><strong><em>Answer</em></strong>: Yes, as long as the application conform to logo requirements. Sometimes older runtime libraries violate security rules (es. Write access to WRP resources) or reliability rules (es. Fail APPVerifier checks). Migration to Framewark 2 is recommended but not required. In such cases, the ISV can contact <a href="mailto:swlogo@microsoft.com">swlogo@microsoft.com</a> to work out solutions on a case by case basis. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Do Vista Logo requirements allow using "Always Override" logic for a content file that cannot be versioned (es. a text file) installed by a setup program? 
</p><p><strong><em>Answer</em></strong>: Yes. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How is it possible to obtain certificates for signing exes and Dlls? How much does it cost? 
</p><p><strong><em>Answer</em></strong>: Certificates can be obtained from third party Certificate Authorities such as Verisign or Geotrust. soft Windows Vista Software Logo Program Participants Only can get a certificate from Verisign at a discounted rate. For additional information see <a href="https://securitycenter.verisign.com/celp/enroll/upsell?application_locale=VRSN_US&amp;originator=VRSN_TEST&amp;additional_field9=VRSN_ADD9&amp;bundle_id=MSIECS002&amp;promo_code=N52A637&amp;enable_options=validity_1">Microsoft Authenticode Code Signing Digital ID</a>
	</p><p>     
 </p><p><strong><em>Question</em></strong>: How is it possible to integrate Windows Error Reporting? 
</p><p><strong><em>Answer</em></strong>: This is possible submitting your application and registering on the <strong><em>winqual site</em></strong>. <br/>This requires using a product identifier tool that maps the applications unique identifier onto the <strong><em>Windows Error Reporting site</em></strong>. Every error submitted through WER is grouped by offending application. An ISV can then log on to the WER site and look at the reports for their applications. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: is it possible to certify Smart document applications or Add-ins? 
</p><p><strong><em>Answer</em></strong>: No, If an application must run on top of another application, similar to a plug in, the application does not qualify as a native Windows Vista application. The application must be a native standalone project to qualify for the Logo program. 
</p><p>   
 </p><p><strong><em>Question</em></strong>: how much does it cost submitting an application for Vista Certification? 
</p><p><strong><em>Answer</em></strong>: testing fee for one application is about 1000 USD; If there is a failure in any of the tests the application will need to be corrected and resubmitted at an extra charge, typically around 500 USD per retest. This is why it is recommended to check that the application verify all Test Cases described in "<a href="https://download.microsoft.com/download/8/e/4/8e4c929d-679a-4238-8c21-2dcc8ed1f35c/Windows%20Vista%20Software%20Logo%20Spec%201.1.doc">Certified for Windows Vista Test Cases</a>". Pretesting is available (but not required) at an extra cost through both VeriTest (<a href="https://www.lionbridge.com/lionbridge/en-US/services/outsourced-testing/product-certification-programs/microsoft/certified-for-windows-vista/default.htm">Certified for Windows Vista</a>) and Wipro (<a href="https://www.wipro.com/microsoft/certification/" title="https://www.wipro.com/microsoft/certification/"><span style="font-family:Arial; font-size:10pt">https://www.wipro.com/microsoft/certification/</span></a>). 
</p><p>   
 </p><h1>FAQ on Windows Vista Compatibility 
</h1><p><strong><em>Question</em></strong>: What areas may cause incompatibility for applications on Vista? 
</p><p><strong>Answer</strong>: Most aspects are documented in "<a href="https://devreadiness.org/files/5/white_papers/entry10.aspx"><span style="color:blue; text-decoration:underline"><em>The Windows Vista Developer Story Application Compatibility Cookbook</em></span></a>". 
</p><p>Important aspects include: 
</p><ul><li>User Account Control 
</li><li>Windows Resource Protection 
</li><li>Internet Explorer Protected Mode 
</li><li>Session 0 Isolation 
</li><li>Deprecated components 
</li><li>Changes in the standard file system standard folders and applications location. 
</li></ul><p>     
 </p><p><strong><em>Question</em></strong>: Is there a list of the APIs that require Admin Privilege available? 
</p><p><strong>Answer</strong>: No, an API may require Admin Privilege depending on the ACLs on objects it manages. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Can .Net Applications address more than 2GB memory on Windows Vista 64bit? 
</p><p><strong>Answer</strong>: .Net Applications can address 16TB memory on 64Bit platfrom (instead of 4GB).<br/>However, there is a 2GB limit on the size of every single object you create. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How is it possible to elevate an application to use Admin Privilege? 
</p><p><strong>Answer</strong>: Elevation can be: 
</p><ul><li>forced by the developer <strong><em>adding a manifest</em></strong> to the application. 
</li><li>forced by the user with "<strong><em>run as administrator</em></strong>" command. 
</li><li><div>forced by the developer for a component using the "<strong><em>Elevation moniker</em></strong>". 
</div><p style="margin-left: 18pt">     
 </p></li></ul><p><strong><em>Question</em></strong>: how is it possible to understand if a user is currently running with the filtered access token? 
</p><p><strong>Answer</strong>: Use <strong><em>OpenProcessToken</em></strong>(GetCurrentProcess()…) and <strong><em>GetTokenInformation</em></strong>( … TokenElevationType… ); and check TokenElevationType: 
</p><ul><li>TokenElevationTypeDefault: The process user is not using a filtered token (i.e. it is a standard user, or UAC disabled for the user). 
</li><li>TokenElevationTypeFull: The process has a split token and is running elevated. 
</li><li>TokenElevationTypeLimited: The process has a split token and is running as standard-user. 
</li></ul><p>     
 </p><p><strong><em>Question</em></strong>: how is it possible to read all of the access tokens associated to a user (i.e. the filtered access token and the real user token) 
</p><p><strong>Answer</strong>: use <strong><em>OpenProcessToken</em></strong>(GetCurrentProcess()…) and <strong><em>GetTokenInformation</em></strong>. To detect if the user has two tokens. 
</p><p>If you have 2 tokens and you are running with the filtered token, use the ShellExecuteEx() or the elevation moniker to run a process with the unfiltered token. 
</p><p>If you have 2 tokens and you are running with the unfiltered token, use the ShellExecuteEx() to run a process with the filtered token. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: What is Session 0 Isolation and how may it cause incompatibility to Windows applications and services? 
</p><p><strong>Answer</strong>: In Vista, Services are run on an <strong><em>isolated</em></strong> and <strong><em>non-interactive session</em></strong> (<strong><em>Session 0</em></strong>).<br/>In Vista, a new session is created for every user logging on.<br/>So services never run on the same session of user applications 
</p><p>This is different from earlier OSs where the first logged on user is run within Session 0. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How is it possible to understand if an "<strong><em>Access Denied</em></strong>" error message comes from WRP or from another source?  
</p><p><strong>Answer</strong>: You can attach Appverifier to the application and run a Luapriv check.  Look at the logs generated and you are looking for any message with a severity = "error" and that is accessing a WRP resource  
</p><p>     
 </p><p><strong><em>Question</em></strong>: Is the EXE manifest file used to specify UAC Execution Level the same manifest file used for COM side by side execution? 
</p><p><strong>Answer</strong>: Yes, the manifest file can be embedded as an exe resource and it can also be used as an external file; having a manifest as an external file may not work for all scenarios. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Is Restart Manager a Windows Vista only technology? Can setup programs using Restart Manager be used on Windows XP also? 
</p><p><strong>Answer</strong>: Restart Manager is available for Microsoft Windows Server "Longhorn" and Windows Vista only. To use restart manager all you need is the MsiRMFilesInUse dialog. The presence of the dialog is simply ignored on down-level systems and the default "files in use behavior" is used. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Is Windows Installer 4 Technology only available on Windows Vista? Does using installer 4 technology require that separate installs be created for windows XP? 
</p><p><strong>Answer</strong>: Windows Installer 4.0 is available only on "Microsoft Windows Server Longhorn" and "Microsoft Windows Vista" but it doesn't change the msi database format. Using Windows Vista Only technologies such as the restart manager just lights up on Vista and doesn't require building a separate installation for down-level platforms (ex. Windows XP). 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How does Vista identify an Executable or application as a setup program? 
</p><p><strong>Answer</strong>: Before a 32 bit process is created, the following attributes are checked to determine whether it is an installer: 
</p><ul><li>Filename includes keywords like "install," "setup," "update," etc. 
</li><li>Keywords in the following Versioning Resource fields: Vendor, Company Name, Product Name, File Description, Original Filename, Internal Name, and Export Name. 
</li><li>Keywords in the side-by-side manifest embedded in the executable. 
</li><li>Keywords in specific StringTable entries linked in the executable. 
</li><li>Key attributes in the RC data linked in the executable. 
</li><li>Targeted sequences of bytes within the executable. 
</li><li>Due to the intricate nature of install detection heuristics, the recommendation is to embed an application manifest in all executables with an appropriate requestedExecutionLevel to declare the desired runtime access. It is not recommend to try to avoid heuristics, as there might be some other matching characteristic of the binary that cannot be easily modified. 
</li></ul><p>See <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=ba73b169-a648-49af-bc5e-a2eebb74c16b&amp;DisplayLang=en">Windows Vista Application Development Requirements for User Account Control Compatibility</a> for additional information. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Is Visual Studio 2003 supported on Vista? 
</p><p><strong>Answer</strong>: Changes in Windows vista impact Visual Studio so that Microsoft is unable to provide support for Visual Studio .NET 2002 or Visual Studio .NET 2003 on Windows Vista. see <a href="https://msdn2.microsoft.com/en-us/vstudio/aa948853.aspx">Visual Studio on Windows Vista</a> for additional information. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: Are Framework 1.0 and Framework 1.1 supported on Vista? 
</p><p><strong>Answer</strong>: Framework 1.1 is a 32bit only technology and it is supported on windows Vista. 
</p><p>Framework 1.0 is not supported on windows Vista and Framework 1.0 assemblies may be run with Framework 1.1 runtime. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How is it possible to integrate custom application data into <strong><em>Windows Vista Search</em></strong>? 
</p><p><strong>Answer</strong>: Create an iFilter provider. <a href="https://msdn.microsoft.com/library/default.asp?url=/library/en-us/odc_SP2003_ta/html/ODC_HowToWriteaFilter.asp">How to Write a Filter for Use by SharePoint Portal Server 2003 and Other Microsoft Search-Based Products</a>. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: How exactly is it possible to apply an application compatibility fix to an EXE and deploy it to corporate computers? 
</p><p><strong>Answer</strong>: Generate a new SDB using ACT 5.0 "<strong><em>Compatibility Administrator</em></strong>" then invoke <strong><em>sdbinst.exe</em></strong> to install the custom sdb to machines system32 folder. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: how is it possible to embed a certificate into <strong><em>MsiPatchCertificate table</em></strong>. 
</p><p><strong>Answer</strong>:see <a href="https://technet.microsoft.com/en-us/windowsvista/aa905117.aspx">Understanding and Configuring User Account Control in Windows Vista</a>. 
</p><p>     
 </p><p><strong><em>Question</em></strong>: how is it possible to embed a certificate into an executable. 
</p><p><strong>Answer</strong>:see <a href="https://www.microsoft.com/downloads/details.aspx?FamilyID=BA73B169-A648-49AF-BC5E-A2EEBB74C16B&amp;displaylang=en">Windows Vista Application Development Requirements for User Account Control Compatibility</a>. 
</p><p>     
 </p><p>     
 </p><p>    </p>]]></content:encoded>
    </item>
    <item>
      <title>Write your services leveraging existing thread pool technologies</title>
      <link>https://docs.microsoft.com/archive/blogs/darioa/write-your-services-leveraging-existing-thread-pool-technologies</link>
      <pubDate>Fri, 15 Sep 2006 08:16:00 GMT</pubDate>
      <dc:creator><![CDATA[darioa]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/darioa/2006/09/15/write-your-services-leveraging-existing-thread-pool-technologies/</guid>
      <description><![CDATA[here is an idea on how to write your services leveraging the power of existing thread pool...]]></description>
      <content:encoded><![CDATA[<p>here is an idea on how to write your services leveraging the power of existing thread pool technologies.</p>
<p>Thread pooling is important for scalability. <br />Pooling algorithms generally include complex logic for self tuning, queuing incoming requests, etc. <br />These are some of the reasons why I'd rather not bother writing thread pooling code in my services and leverage existing technologies instead.</p>
<p>In this article I provide a sample code for a service to receive messages from a MSMQ queue and process them by means of the ASPNet Thread Pool. <br />Similar code can be written to receive commands from a socket or some other source.</p>
<p>The code is divided into 3 sections:</p>
<ul>
<li><strong><em>WAITING SECTION</em></strong> (<em>PeekWorkItem()</em> method): this section is used to enter wait mode ('<strong><em>peek mode</em></strong>') on the resource (the queue). Only one thread is allowed to enter 'peek mode' to avoid too many callbacks when a new message arrives. 'peek mode' is represented by flag <em>_nIsPeekActive</em> which is protected against concurrency. <br />In case of exceptions (es. because of MSMQ service down) a new PeekWorkItem() is submitted with a delay to avoid 100% CPU loops on error conditions.</li>
<li><strong><em>WAKE UP SECTION</em></strong> (<em>PeekCompleted()</em> method): this section is run when a new message arrives on the queue. In this section a number of requests are submitted to the thread pool to read messages from the queue and process them. <br />The code keeps count of the number of requests submitted to the thread pool (into variable <em>_nReceiveCount</em>). It is the thread pool choice to really process those requests concurrently or to serve them in a more scattered way. In case of exceptions (es. because of MSMQ service down) a new PeekWorkItem() is submitted with a delay to avoid 100% CPU loops on error conditions.</li>
<li><strong><em>RECEIVE SECTION</em></strong> (<em>ReceiveWorkItem()</em> method): this section is the work item run by the thread pool that reads messages from the queue and process them. <br />Code sections run on a thread pool should never be 'too short' or 'too long' as that may waste resources. So, ReceiveWorkItem() is designed to read and process as many messages as possible up to a configurable timeout (or the queue becomes empty).</li>
</ul>
<p><span style="color: #4f81bd; font-size: 9pt;"><strong><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0385.Figure%201%20msmq%20custom%20listener%20engine.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0385.Figure-1-msmq-custom-listener-engine.jpg"><img border="0" alt="" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/67/35/0385.Figure%201%20msmq%20custom%20listener%20engine.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-00-67-35/0385.Figure-1-msmq-custom-listener-engine.jpg" width="627" height="286" /></a>&nbsp;</strong></span></p>
<p><span style="color: #4f81bd; font-size: 9pt;"><strong>Figure 1: MSMQ Custom Listener engine </strong></span></p>
<h1>WAITING SECTION (PeekWorkItem() method)</h1>
<p>IO mechanisms generally provide asynchronous ways of receiving data.<br />This saves the need of creating threads just to wait on them.<br />In facts, there are cheaper ways to wait on empty resources, which are usually exposed as Asynchronous APIs.<br />.Net MSMQ asynchronous API to read messages from a queue is <em>Queue.BeginPeek()</em> method.<br /><br /><strong><em>PeekWorkItem()</em></strong> is the code section where my service calls <em><strong>_queue.BeginPeek</strong>()</em> method to look for messages into the MSMQ queue.<br /><em>_queue</em> variable refers to the queue the service is looking for messages from.<br /><br />Before calling <em>_queue.BeginPeek()</em>, <em>PeekWorkItem()</em> sets flag <em>_nIsPeekActive</em> to 1 (i.e. it enters '<em>Peek mode</em>').</p>
<p><em>_nIsPeekActive</em> flag keeps track that somebody is waiting on the queue and avoids other threads call <em>BeginPeek</em>() on it.<br />This reduces the number of callbacks that are processed when new messages arrive on the queue.<br />&nbsp;</p>
<p>If <em>_queue</em> is empty, <em>_queue.BeginPeek()</em> doesn't block the calling thread.<br />So, no thread objects are wasted waiting on empty queues and no threads are kept blocked for long time.<br />That's why, <em>PeekWorkItem()</em> may safely be run on thread pool threads.<br />&nbsp;</p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">#region</span><span style="font-family: Lucida Console;"> PeekWorkItem</span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> </span><span style="color: gray; font-family: Lucida Console;">&lt;summary&gt;</span><span style="color: green; font-family: Lucida Console;">submits a BeginPeek() to the queue.</span><span style="color: gray;"><span style="font-family: Lucida Console;">&lt;/summary&gt;</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> </span><span style="color: gray; font-family: Lucida Console;">&lt;remarks&gt;</span><span style="color: green;"><span style="font-family: Lucida Console;">only one BeginPeek() may be active on the queue at any moment.</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green;"><span style="font-family: Lucida Console;"> BeginPeek() invocation is protected by the synchronized flag 'IsPeekActive' which is set just before calling it and reset at the PeekCompleted() callback.</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> In case BeginPeek fails (ex. because of invalid access or any other reason) 'IsPeekActive' is also reset and a delayed peek is submit to check whether it may succeed at a later time.</span><span style="color: gray;"><span style="font-family: Lucida Console;">&lt;/remarks&gt;</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">public</span><span style="font-family: Lucida Console;"> <span style="color: blue;">void</span> <strong><em>PeekWorkItem()</em></strong> {</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">try</span><span style="font-family: Lucida Console;"> {</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// Try a BeginPeek() on the queue; if _nIsPeekActive==1 somebody else is in peek mode, so, PeekWorkItem does nothing... </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (Interlocked.CompareExchange(<span style="color: blue;">ref</span> _nIsPeekActive, 1, 0) == 0) { </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// Entering Peekmode: Only one thread is allowed to call BeginPeek() to prevent too many callbacks when a new message arrives </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">_queue.BeginPeek(MessageQueue.InfiniteTimeout, <span style="color: blue;">null</span>, <span style="color: blue;">new</span> AsyncCallback(PeekCompleted)); </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">} <span style="color: blue;">catch</span> (Exception ex) { </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// Submit a delayed PeekWorkItem() and ignore the exception. </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// BeginPeek may fail when there are problems with the MSMQ service. </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// The new PeekWorkItem() is delayed to avoid an loop with 100% CPU in such case. </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">ICall call = <span style="color: blue;">new</span> DelayedCall(<span style="color: blue;">new</span> DelegateCall(<span style="color: blue;">new</span> VoidEmptyArgsDelegate(PeekWorkItem)), _nPeekDelayOnException);</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// Release _nIsPeekActive flag: the next PeekWorkItem() will be allows to enter peekmode! </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">Interlocked.Exchange(<span style="color: blue;">ref</span> _nIsPeekActive, 0);</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// Start the delayed PeekWorkItem() and save the call object into '_call member'. </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// if '_call member' already contains a delayed call object dispose it to have only one active call object at a time </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">call.Invoke(); </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">IDisposable oldCall = Interlocked.Exchange&lt;ICall&gt;(<span style="color: blue;">ref</span> _call, call) <span style="color: blue;">as</span> IDisposable; </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (oldCall != <span style="color: blue;">null</span>) { oldCall.Dispose(); }</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">#endregion </span> </span></p>
<h1>WAKE UP SECTION (PeekCompleted() method)</h1>
<p>The wake up section is run when new messages arrive on the queue (or, exceptional conditions happen waiting on it).<br />In facts <strong><em>PeekCompleted()</em></strong> method was registered as a callback on the queue, in the 'waiting section', when calling <em>BeginPeek()</em> method.<br />Remember that only one thread is allowed to set <em>_nIsPeekActive</em> flag and call <em>_queue.BeginPeek()</em>.<br />So, only one callback is run when messages arrive on the queue.<br /><br />Just after wake up, <em>PeekCompleted()</em> calls <em>_queue.EndPeek()</em> to check whether new messages are available on the queue.</p>
<p>If <em>_queue.EndPeek()</em> succeeds, there are messages available so, <em>PeekCompleted() </em>submits some requests for processing them (i.e. delegates to <em>ReceiveWorkItem()</em>), to the thread pool.<br /><em>PeekCompleted()</em> doesn't use the message returned by <em>_queue.EndPeek()</em>; in facts, it is the Receive section that chooses how to receive messages, whether to share the receive transaction with the message processing etc.<br /><br /><em>PeekCompleted()</em> keeps count of the requests currently submitted to the thread pool by means of variable <em>_nReceiveCount</em>.<br />In facts, <em>PeekCompleted()</em> increments <em>_nReceiveCount</em> every time it submits a request for processing to the thread pool and, in turn, <em>_nReceiveCount</em> is decremented every time a thread pool request completes. &nbsp; &nbsp;</p>
<p><em>PeekCompleted()</em> makes sure that requests for message processing are sent to the thread pool with <em>_nReceiveCount </em>up to a configurable limit (held in variable <em>_nMaxConcurrency)</em>.<br /><br /><em>PeekCompleted()</em> releases <span style="text-decoration: underline;">always</span> <em>_nIsPeekActive</em> flag: it does that before sending the last request for processing or in the finally block.<br />This allows a new thread enter 'peek mode', when the queue becomes empty or some receive work item complete for other reasons (e.g. by timeout).<br /><br />In case of exceptions there might be problems on the queue so (after releasing _nIsPeekActive flag) <em>PeekCompleted()</em> submits a delayed request to <em>PeekWorkItem()</em> (the waiting section).<br />The delay is necessary to prevent a CPU overhead on the PeekWorkItem()/PeekCompleted() loop during the exceptional condition.</p>
<p>&nbsp; &nbsp; &nbsp;</p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">#region</span><span style="font-family: Lucida Console;"> PeekCompleted</span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> </span><span style="color: gray; font-family: Lucida Console;">&lt;summary&gt;</span><span style="color: green; font-family: Lucida Console;">PeekCompleted is triggered when a BeginPeek() is active and any message is received by the queue.</span><span style="color: gray;"><span style="font-family: Lucida Console;">&lt;/summary&gt;</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> </span><span style="color: gray; font-family: Lucida Console;">&lt;remarks&gt;</span><span style="color: green;"><span style="font-family: Lucida Console;">PeekCompleted resets 'IsPeekActive' and submits an appropriate number of ReceiveWorkItems to the thread pool for receiving messages.</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green;"><span style="font-family: Lucida Console;"> ReceiveWorkItems are submitted according to the concurrency configuration setting for the queue.</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: gray; font-family: Lucida Console;">///</span><span style="color: green; font-family: Lucida Console;"> currently active ReceiveWorkItems can be monitored by means of 'Requests Current' performance counter.</span><span style="color: gray;"><span style="font-family: Lucida Console;">&lt;/remarks&gt;</span> </span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">public</span><span style="font-family: Lucida Console;"> <span style="color: blue;">void</span> <strong><em>PeekCompleted(IAsyncResult asyncResult)</em></strong> {</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">bool</span><span style="font-family: Lucida Console;"> bPeekActiveReset = <span style="color: blue;">false</span>;</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">try</span><span style="font-family: Lucida Console;"> {</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// any BeginPeek() must be matched with an EndPeek()... </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">Message msg = <span style="color: blue;">this</span>._queue.EndPeek(asyncResult); </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// "Submits receive requests up to the maximun concurrency allowed; current ReceiveCount '_nReceiveCount', Max Concurrency '_nMaxConcurrency'." </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">int</span><span style="font-family: Lucida Console;"> nReceiveCount = Interlocked.CompareExchange(<span style="color: blue;">ref</span> _nReceiveCount, -1, -1); <span style="color: green;">// access to _nReceiveCount is sinchronized to allow </span></span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">for</span><span style="font-family: Lucida Console;"> (; nReceiveCount &lt; _nMaxConcurrency; ) {</span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">nReceiveCount = Interlocked.Increment(<span style="color: blue;">ref</span> _nReceiveCount); </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (nReceiveCount &lt;= _nMaxConcurrency) {</span> </span></p>
<p style="margin-left: 144pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// "Releases the peekactive mode before sending the last ReceiveWorkItem()" </span> </span></p>
<p style="margin-left: 144pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (nReceiveCount == _nMaxConcurrency) { Interlocked.Exchange(<span style="color: blue;">ref</span> _nIsPeekActive, 0); bPeekActiveReset = <span style="color: blue;">true</span>; }</span> </span></p>
<p style="margin-left: 144pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">ThreadPool.QueueUserWorkItem(<span style="color: blue;">new</span> WaitCallback(ReceiveWorkItem), <span style="color: blue;">this</span>); </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">} <span style="color: blue;">catch</span> (Exception ex) {</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: green; font-family: Lucida Console;">// trace a warning and submits a delayed PeekWorkItem() in the finally block. </span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">} <span style="color: blue;">finally</span> {</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (bPeekActiveReset == <span style="color: blue;">false</span>) { <span style="color: green;">// Submits a delayed PeekWorkItem()</span></span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">ICall call = <span style="color: blue;">new</span> DelayedCall(<span style="color: blue;">new</span> DelegateCall(<span style="color: blue;">new</span> VoidEmptyArgsDelegate(PeekWorkItem)), _nPeekDelayOnException);</span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">Interlocked.Exchange(<span style="color: blue;">ref</span> _nIsPeekActive, 0); </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">call.Invoke(); </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">IDisposable oldCall = Interlocked.Exchange&lt;ICall&gt;(<span style="color: blue;">ref</span> _call, call) <span style="color: blue;">as</span> IDisposable; </span> </span></p>
<p style="margin-left: 108pt;"><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">if</span><span style="font-family: Lucida Console;"> (oldCall != <span style="color: blue;">null</span>) { oldCall.Dispose(); }</span> </span></p>
<p style="margin-left: 72pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p><span style="font-size: 9pt;"><span style="font-family: Lucida Console;">}</span> </span></p>
<p><span style="font-size: 9pt;"><span style="color: blue; font-family: Lucida Console;">#endregion </span> </span></p>
<p>&nbsp; &nbsp; &nbsp;</p>
<h1>RECEIVE SECTION (ReceiveWorkItem() method)</h1>
<p><strong><em>ReceiveWorkItem()</em></strong> is run on the thread pool to receive messages from the queue and process them.<br />Code sections run on a thread pool should never be 'too short' or 'too long' as that may waste resources.<br />For this reason <em>ReceiveWorkItem()</em> is designed to process multiple messages up to a configurable time interval (<em>_nWorkItemTimeLimit</em> variable) or the queue becomes empty.<br /><br />if the queue becomes empty, every running <em>ReceiveWorkItem()</em> completes and (only) the last one processes a <em>PeekWorkItem()</em> to enter '<em>Peek Mode</em>' on the queue.<br />Also, <em>PeekWorkItem() </em>is processed when a <em>ReceiveWorkItem()</em> completes because of <em>_nWorkItemTimeLimit </em>expiration.<br />if a <em>ReceiveWorkItem() </em>completes because of an exception receiving or processing a message, the call to <em>PeekWorkItem() </em>is delayed to limit CPU overhead in exceptional conditions.<br /><br />In case of failures processing a message, <em>ReceiveWorkItem() </em>tries to save the failed message to a '_failedmessages' queue by means of <em>hlpSaveDeadMessage()</em> method.<br /><br /><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">#region</span> ReceiveWorkItem </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;summary&gt;</span><span style="color: green;">ReceiveWorkItem is processed on the thread pool to receive messages from the queue and process them.</span><span style="color: gray;">&lt;/summary&gt;</span> </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: gray;">///</span><span style="color: green;"> </span><span style="color: gray;">&lt;remarks&gt;</span><span style="color: green;">ReceiveWorkItem retrieves messages according to the configuration and process them. </span> </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: gray;">///</span><span style="color: green;"> in case of a processing failure a message, ReceiveWorkItem() tries to save the failed message to the '_failedmessages' queue. </span> </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: gray;">///</span><span style="color: green;"> the move of the message to the failedmessages queue is performed with the same transactional settings used for retrieval from the original queue. in case of failure saving the message to the failedmessages queue the original message is restored to the original queue ONLY if the queue is configured for use of external transactions.</span><span style="color: gray;">&lt;/remarks&gt; </span> </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">public</span> <span style="color: blue;">void</span> <strong><em>ReceiveWorkItem(<span style="color: blue;">object</span> oThis)</em></strong> { </span></p>
<p style="margin-left: 36pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">int</span> nReceiveCount = 0; <span style="color: blue;">bool</span> bIsEmpty = <span style="color: blue;">false</span>; <span style="color: blue;">bool</span> bDelayPeekWorkItem = <span style="color: blue;">false</span>; <span style="color: blue;">string</span> sMessageId = <span style="color: blue;">null</span>; </span></p>
<p style="margin-left: 36pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">try</span> { </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// Receives a message from the queue '_queue' with transaction mode '_transactionType' (ReceiveCount: '_nReceiveCount') </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">DateTime dtExpiration = DateTime.MinValue; <span style="color: blue;">if</span> (_nWorkItemTimeLimit &gt;= 0) { dtExpiration = DateTime.Now.AddMilliseconds(_nWorkItemTimeLimit); } </span></p>
<p style="margin-left: 72pt;">&nbsp; &nbsp; &nbsp;</p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">for</span> (<span style="color: blue;">bool</span> bTimeLimitExceeded = <span style="color: blue;">false</span>; bIsEmpty == <span style="color: blue;">false</span> &amp;&amp; bTimeLimitExceeded == <span style="color: blue;">false</span>; sMessageId = <span style="color: blue;">null</span>) { </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;">Message oMessage = <span style="color: blue;">null</span>; <span style="color: blue;">bool</span> bIsReceiveCommitted = <span style="color: blue;">false</span>; </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">try</span> { </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// creates a transaction scope for use of external transactions. A null transaction scope is used otherwise"); </span> </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">TransactionScope oTransactionScope = (_transactionType == MessageQueueTransactionType.Automatic) ? <span style="color: blue;">new</span> TransactionScope(TransactionScopeOption.RequiresNew) : <span style="color: blue;">null</span>; </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">using</span> (oTransactionScope) { </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">try</span> { oMessage = _queue.Receive(TimeSpan.Zero, _transactionType); } </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">catch</span> (MessageQueueException tex) { </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (tex.MessageQueueErrorCode == MessageQueueErrorCode.IOTimeout) { bIsEmpty = <span style="color: blue;">true</span>; } </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">else</span> { <span style="color: blue;">throw</span>; } </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (_transactionType != MessageQueueTransactionType.Automatic) { bIsReceiveCommitted = <span style="color: blue;">true</span>; } </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (oMessage != <span style="color: blue;">null</span>) { </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// Processing message 'oMessage.Id' </span> </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;">sMessageId = oMessage.Id; </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (_formatter != <span style="color: blue;">null</span>) { oMessage.Formatter = _formatter; } </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;">ServiceMessage oServiceMessage = (ServiceMessage)oMessage.Body; </span></p>
<p style="margin-left: 216pt;"><span style="font-family: Lucida Console; font-size: 9pt;">ServiceMessage oRetMessage = hlpProcessMessage(oServiceMessage); </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 180pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (_transactionType == MessageQueueTransactionType.Automatic) { oTransactionScope.Complete(); } </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} <span style="color: blue;">catch</span> (Exception ex) { </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (sMessageId == <span style="color: blue;">null</span>) { <span style="color: blue;">throw</span> <span style="color: blue;">new</span> CommunicationEngineTargetException(<span style="color: blue;">string</span>.Format(<span style="color: maroon;">"Exception '{0}' - '{1}' occurred receiving a message from queue '{2}' and the message ID could not be retrieved; the message cannot be saved to the deadqueue. If the queue is not configured with automatic transactions the message may be lost."</span>, ex.GetType().Name, ex.Message, _queueConf.FormatName)); } </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">bIsEmpty = hlpSaveDeadMessage(sMessageId, oMessage, <span style="color: blue;">ref</span> bIsReceiveCommitted); </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (bIsReceiveCommitted == <span style="color: blue;">false</span>) { bDelayPeekWorkItem = <span style="color: blue;">true</span>; <span style="color: blue;">return</span>; } </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (_nWorkItemTimeLimit &gt;= 0 &amp;&amp; dtExpiration &lt;= DateTime.Now) { bTimeLimitExceeded = <span style="color: blue;">true</span>; } </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 36pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} <span style="color: blue;">catch</span> (Exception ex) { </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// "Exception occurred receiving a message from queue '_queue'; message id is 'sMessageId' </span> </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">bDelayPeekWorkItem = <span style="color: blue;">true</span>; <span style="color: green;">// "Ignores the exception. and run finally block</span> </span></p>
<p style="margin-left: 36pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} <span style="color: blue;">finally</span> { </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">nReceiveCount = Interlocked.Decrement(<span style="color: blue;">ref</span> _nReceiveCount); </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">PublishEndRequestCounters(_queueConf); </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (!bIsEmpty || nReceiveCount == 0) { </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (!bDelayPeekWorkItem) { </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// Submits a PeekWorkItem() </span> </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">PeekWorkItem(); </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} <span style="color: blue;">else</span> <span style="color: blue;">if</span> (nReceiveCount == 0) { </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: green;">// Submits a delayed PeekWorkItem() </span> </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">ICall call = <span style="color: blue;">new</span> DelayedCall(<span style="color: blue;">new</span> DelegateCall(<span style="color: blue;">new</span> VoidEmptyArgsDelegate(PeekWorkItem)), _nPeekDelayOnException); </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">call.Invoke(); </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;">IDisposable oldCall = Interlocked.Exchange&lt;ICall&gt;(<span style="color: blue;">ref</span> _call, call) <span style="color: blue;">as</span> IDisposable; </span></p>
<p style="margin-left: 144pt;"><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">if</span> (oldCall != <span style="color: blue;">null</span>) { oldCall.Dispose(); } </span></p>
<p style="margin-left: 108pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 72pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p style="margin-left: 36pt;"><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;">} </span></p>
<p><span style="font-family: Lucida Console; font-size: 9pt;"><span style="color: blue;">#endregion </span> </span></p>
<p>&nbsp;&nbsp;&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/00/75/58/23/20060908%20Write%20your%20services%20leveraging%20existing%20thread%20pool%20technologies%20Figure%201.JPG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-00-75-58-23/20060908-Write-your-services-leveraging-existing-thread-pool-technologies-Figure-1.JPG">20060908 Write your services leveraging existing thread pool technologies Figure 1.JPG</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>