<?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>Dustin Metzgar's blog</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/dmetzgar/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/dmetzgar/feed.xml</link>
    <description>Mostly software performance</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:20:28 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Performance Monitor Issues</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/performance-monitor-issues</link>
      <pubDate>Mon, 26 Aug 2013 13:14:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/08/26/performance-monitor-issues/</guid>
      <description><![CDATA[Performance counters are an essential part of any Windows programmer's diet. They have been around...]]></description>
      <content:encoded><![CDATA[<p>Performance counters are an essential part of any Windows programmer's diet. They have been around forever and the infrastructure is rarely updated (last time I think was in Vista). IT pros&nbsp;couldn't live without them. Performance and stress testing rely on them. They are a very important part of Windows.</p>
<p>But there are problems with performance counters. Problems that should be fixed but seem to receive no attention. Here is my list.</p>
<h3>1. Performance Monitor shows different data on different machines</h3>
<p>Performance counter data can be recorded to files using <a title="logman" href="https://technet.microsoft.com/en-us/library/bb490956.aspx">logman</a>. The resulting files have a .blg extension.&nbsp;This is great for performance testing since I can keep all the perf counter data in a compact log file for each test. The problem comes when I try to view these blg files. Here is a file that was produced on a Windows Server 2008 R2 VM opened in performance monitor on a different VM with the same OS:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/8512.Win2008R2PerfMon.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/8512.Win2008R2PerfMon.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/8512.Win2008R2PerfMon.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/8512.Win2008R2PerfMon.PNG" alt="" border="0" /></a></p>
<p>Now here is the same blg file opened from&nbsp;a Windows 8 machine:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2577.Win8PerfMon.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2577.Win8PerfMon.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2577.Win8PerfMon.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2577.Win8PerfMon.PNG" alt="" border="0" /></a></p>
<p>This is not consistent either. Most of the time I can open BLG files on my Windows 8 machine without a problem. The trouble is I don't know if it's limited to just&nbsp;Windows 8.</p>
<p>The good thing is that this is just a viewer. The blg file still has the correct data. So how about using a different viewer?</p>
<h3>2.&nbsp;There are no libraries to read BLG files</h3>
<p>Microsoft has never published the official&nbsp;specifications for the BLG format. There are no libraries&nbsp;available to read the format either. It is possible to reverse-engineer&nbsp;the file format to create a library, but you can never be 100% certain that&nbsp;it works in all situations. Given the inconsistencies in the viewers, I wonder if Microsoft itself has lost the specifications for this file format.</p>
<p>The good thing is that you can convert BLG to CSV format using <a title="relog" href="https://technet.microsoft.com/en-us/library/bb490958.aspx">relog</a>.</p>
<h3>3. &nbsp;The first line of a converted CSV has empty values</h3>
<p>When you convert a BLG file to a CSV, the first line below the header contains some empty values. In relog you can specify a -b parameter to begin at a different timestamp. No matter what you set this to, the first line of the CSV has empty values. Here is a look at a converted file:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/0741.RelogCsv1.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/0741.RelogCsv1.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/0741.RelogCsv1.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/0741.RelogCsv1.PNG" alt="" border="0" /></a></p>
<p>The first line has empty spaces in it for some of the values but not all. If you move to 5:22:42 (since the -b parameter is only good up to seconds), you'll get this instead:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2804.RelogCsv2.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2804.RelogCsv2.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2804.RelogCsv2.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2804.RelogCsv2.PNG" alt="" border="0" /></a></p>
<p>While this isn't a big deal, it does mean that if you want counters from a specific time period, you have to factor in that this first line tends to be incomplete.</p>
<h3>4. Combining several BLGs into one&nbsp;is limited to 32 files and has poor error messages&nbsp;</h3>
<p>Let's say I set up a rolling log in logman to generate a new BLG file every 10 minutes. I want to examine a period of several hours so I take the BLG files generated from that time period. Using relog, I can combine these files into one BLG so that I don't have to open lots of windows and try to understand what happened in what order. In my case, I have 37 BLG files. When I run the command to combine the files, I get a strange error:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/3250.RelogCombine1.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/3250.RelogCombine1.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/3250.RelogCombine1.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/3250.RelogCombine1.PNG" alt="" border="0" /></a></p>
<p>The error "The specified log file type has not been installed on this computer" appears to be a catch-all error for relog. One would think that maybe one of the files is corrupt but I can combine into two different groups and combine the results of that without an issue:</p>
<pre style="font-family: courier new,courier; font-size: x-small; background-color: #dddddd;">C:\Temp\2013-08-08\origin0&gt;relog perfcounters_08080*.blg -o combined0.blg

Input
----------------
File(s):
     perfcounters_08080451.blg (Binary)
     perfcounters_08080501.blg (Binary)
     perfcounters_08080511.blg (Binary)
     perfcounters_08080521.blg (Binary)
     perfcounters_08080531.blg (Binary)
     perfcounters_08080541.blg (Binary)
     perfcounters_08080551.blg (Binary)
     perfcounters_08080601.blg (Binary)
     perfcounters_08080611.blg (Binary)
     perfcounters_08080621.blg (Binary)
     perfcounters_08080631.blg (Binary)
     perfcounters_08080641.blg (Binary)
     perfcounters_08080651.blg (Binary)
     perfcounters_08080701.blg (Binary)
     perfcounters_08080711.blg (Binary)
     perfcounters_08080721.blg (Binary)
     perfcounters_08080731.blg (Binary)
     perfcounters_08080741.blg (Binary)
     perfcounters_08080751.blg (Binary)
     perfcounters_08080801.blg (Binary)
     perfcounters_08080811.blg (Binary)
     perfcounters_08080821.blg (Binary)
     perfcounters_08080831.blg (Binary)
     perfcounters_08080841.blg (Binary)
     perfcounters_08080851.blg (Binary)
     perfcounters_08080901.blg (Binary)
     perfcounters_08080911.blg (Binary)
     perfcounters_08080921.blg (Binary)
     perfcounters_08080931.blg (Binary)
     perfcounters_08080941.blg (Binary)
     perfcounters_08080951.blg (Binary)

Begin:    8/8/2013 4:51:02
End:      8/8/2013 10:01:21
Samples:  18623

100.00%

Output
----------------
File:     combined0.blg

Begin:    8/8/2013 4:51:02
End:      8/8/2013 10:01:21
Samples:  18623

The command completed successfully.

C:\Temp\2013-08-08\origin0&gt;relog perfcounters_08081*.blg -o combined1.blg

Input
----------------
File(s):
     perfcounters_08081001.blg (Binary)
     perfcounters_08081011.blg (Binary)
     perfcounters_08081021.blg (Binary)
     perfcounters_08081031.blg (Binary)
     perfcounters_08081041.blg (Binary)
     perfcounters_08081051.blg (Binary)

Begin:    8/8/2013 10:01:22
End:      8/8/2013 11:01:24
Samples:  3605

100.00%

Output
----------------
File:     combined1.blg

Begin:    8/8/2013 10:01:22
End:      8/8/2013 11:01:24
Samples:  3605

The command completed successfully.

C:\Temp\2013-08-08\origin0&gt;relog combined*.blg -o combined.blg

Input
----------------
File(s):
     combined0.blg (Binary)
     combined1.blg (Binary)

Begin:    8/8/2013 4:51:02
End:      8/8/2013 11:01:24
Samples:  22228

100.00%

Output
----------------
File:     combined.blg

Begin:    8/8/2013 4:51:02
End:      8/8/2013 11:01:24
Samples:  22228

The command completed successfully.</pre>
<p>So perhaps the issue is the number of files. By removing files one at a time, I found that relog will handle 32 files maximum. This is not documented nor is the error message able to communicate this clearly.</p>
<h3>5. Combining&nbsp;BLG files from multiple machines&nbsp;does not work&nbsp;well</h3>
<p>While this may be stretching what relog was intended to do, I think there is a perfectly reasonable case for wanting to do this. If you have a cluster of machines performing the same function, you may want to get an average CPU or a total throughput for the whole cluster. I do this all the time in Azure.&nbsp;If you collect the performance counters from each machine, then it should be straightforward to combine these data. Unfortunately it's not. The counters in the BLG have the machine name included. So when you combine the counters don't mix. You have to do this by hand:</p>
<ol>
<li>Convert each BLG file to a CSV</li>
<li>In each CSV replace the machine name in the perf counter with a generic name like "server"</li>
<li>Read the data from each CSV simultaneously using a rolling window and combine the perf counters in the time window</li>
</ol>
<p>In other words, forget about it and&nbsp;pay for a tool that will do it for you.&nbsp;</p>
<h3>6. Relog has trouble reading dates from the command line</h3>
<p>Look at the following output:</p>
<pre style="font-family: courier new,courier; font-size: x-small; background-color: #dddddd;">c:\test&gt;relog perf1.blg -f csv -o perf1.csv -b "8/31/2013 0:52:14" -e "8/31/2013 1:02:41"

Input
----------------
File(s):
     perf1.blg (Binary)

Begin:    8/31/2013 0:52:16
End:      8/31/2013 1:02:41
Samples:  626

100.00%

Output
----------------
File:     blah.csv

Begin:    8/31/2013 0:52:16
End:      8/31/2013 1:02:41
Samples:  625

The command completed successfully.

c:\test&gt;relog perf1.blg -f csv -o perf1.csv -b "8/31/2013 12:52:14AM" -e "8/31/2013 1:02:41AM"

Input
----------------
File(s):
     perf1.blg (Binary)

Begin:    8/31/2013 0:52:16
End:      8/31/2013 1:02:41
Samples:  626

Error: The time range specified has no overlap with the input logs.</pre>
<p>The relog documentation says you can use timestamps with AM/PM but does not explicitly say you can use 24 hour time. Also, when it shows begin and end, those appear to be the same in both commands. But one works and one does not.</p>]]></content:encoded>
    </item>
    <item>
      <title>Dale Carnegie and the Big Bang Theory</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/dale-carnegie-and-the-big-bang-theory</link>
      <pubDate>Tue, 05 Feb 2013 17:51:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/02/05/dale-carnegie-and-the-big-bang-theory/</guid>
      <description><![CDATA[A recent episode of The Big Bang Theory struck a chord with me. Having attended a Dale...]]></description>
      <content:encoded><![CDATA[<p>A recent episode of The Big Bang Theory struck a chord with me. Having attended a Dale Carnegie&nbsp;(who wrote&nbsp;How to Win Friends and Influence People) course I found it interesting how the character Kripke handled a difficult situation in the show.</p>
<p>Kripke and Sheldon were working on the same project and the university required them to work together. Regular viewers of the show know that Sheldon is very difficult to work with. After reluctantly exchanging notes on their theories, Sheldon was stunned to find out Kripke's theories were better. What I really liked was how Kripke handled the situation. If he gloated, Sheldon would be resistant and the project would suffer.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/4048.Kripke.jpg" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/4048.Kripke.jpg"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/4048.Kripke.jpg" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/4048.Kripke.jpg" alt="" border="0" /></a></p>
<p>Kripke, whether intentionally or not, gave Sheldon a way to save face by attributing his less-than-stellar performance to his preoccupation with his girlfriend. Then Kripke followed up with a compliment by telling Sheldon that he had some great ideas. He then challenged Sheldon to work harder.</p>
<p>In other words,&nbsp;Kripke applied Dale Carnegie principles to turn a difficult person into a willing team member. I have no idea if that was what the show's writers we're going for but I enjoyed the episode.</p>]]></content:encoded>
    </item>
    <item>
      <title>Code Snippets in MSDN Blogs</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/code-snippets-in-msdn-blogs</link>
      <pubDate>Fri, 01 Feb 2013 15:09:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/02/01/code-snippets-in-msdn-blogs/</guid>
      <description><![CDATA[So far in this blog I've experimented with several different ways of writing code snippets. My...]]></description>
      <content:encoded><![CDATA[<p>So far in this blog I've experimented with several different ways of writing code snippets. My favorite way was to use <a href="https://xtractpro.com/tools/CSharp-Highlighter.aspx">XtractPro's syntax highlighter</a>. Unfortunately, the latest version of Telligent seems to resist my efforts by removing all the newlines from my &lt;pre&gt; blocks. That's why I started using <a href="https://gist.github.com">Github Gists</a>. But the problem with that is people using Google Reader cannot see the code snippets.</p>
<p>I'm curious what other people use to write code snippets. I'd be glad to hear any suggestions.</p>]]></content:encoded>
    </item>
    <item>
      <title>Capturing a profile in production based on ETW events</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/capturing-a-profile-in-production-based-on-etw-events</link>
      <pubDate>Thu, 24 Jan 2013 14:49:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/01/24/capturing-a-profile-in-production-based-on-etw-events/</guid>
      <description><![CDATA[ETW has many uses. Filtering allows you to get only the events you want and an out-of-process...]]></description>
      <content:encoded><![CDATA[<p>ETW has many uses. Filtering allows you to get only the events you want and an out-of-process consumer can listen for those filtered events. ETW can also be used for profiling native and managed code. It can sample stacks and mark context switches. That data can be combined with other ETW providers such as the CLR provider which gives you GC events, among other things. ETW profiling can also use circular buffers so that you can leave it on while waiting for an issue to occur and then save the profile for analysis. This trick is especially useful in production where you don't want to make code changes or recycle processes or impact the performance of the process.</p>
<p>The profiler of choice is <a title="PerfView" href="https://www.microsoft.com/en-us/download/details.aspx?id=28567">PerfView</a>. If you search Channel 9 you'll find all kinds of great videos on how to use PerfView for analysis of performance problems. PerfView's command line options allow you to start and stop profiles with separate calls. There is also built-in support to stop collection on performance counters, slow&nbsp;HTTP requests, long GC collects, and events in the Application event log matching a regular expression pattern. However, let's say you are getting an occasional WCF exception in production. Rather than write a message to the Application event log, you could just listen for the event directly.</p>
<p>I put together a C# solution for this using the <a href="https://archive.msdn.microsoft.com/EventTraceWatcher">EventTraceWatcher</a> helper class which is an excellent tool put together by <a href="https://blogs.msdn.com/b/danielvl/archive/2009/02/02/how-to-consume-etw-events-from-c.aspx">Daniel Vasquez Lopez</a>. The main code for this is very straightforward:</p>
<p style="font-family: Courier New;"><span style="color: #008000; font-weight: bold;">using</span>&nbsp;Samples.Eventing;<br /> <span style="color: #008000; font-weight: bold;">using</span>&nbsp;System;<br /> <span style="color: #008000; font-weight: bold;">using</span>&nbsp;System.Diagnostics;<br /> <span style="color: #008000; font-weight: bold;">using</span>&nbsp;System.Threading;<br /> <br /> <span style="color: #008000; font-weight: bold;">namespace</span>&nbsp;CircularTrace<br /> {<br /> &nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #ff0000;">class</span>&nbsp;Program<br /> &nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-weight: bold;">private</span>&nbsp;<span style="color: #a52a2a;">static</span>&nbsp;ManualResetEvent waitForEvent =&nbsp;<span style="color: #008b8b; font-weight: bold;">new</span>&nbsp;<span style="color: #191970; font-weight: bold;">ManualResetEvent</span>(<span style="color: #008b8b; font-weight: bold;">false</span>);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #a52a2a;">static</span>&nbsp;<span style="color: #ff0000;">void</span>&nbsp;<span style="color: #191970; font-weight: bold;">Main</span>(<span style="color: #ff0000;">string</span>[]&nbsp;args)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080; font-weight: bold;">try</span><br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #191970; font-weight: bold;">RunProcess</span>(<span style="color: #0000ff;">"PerfView.exe"</span>,&nbsp;<span style="color: #0000ff;">"start -AcceptEULA -NoGui -Circular:250 -logfile:perfview_start.log -ThreadTime"</span>);<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">// Wait for a WCF exception to occur</span><br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Guid RewriteProviderId =&nbsp;<span style="color: #008b8b; font-weight: bold;">new</span>&nbsp;<span style="color: #191970; font-weight: bold;">Guid</span>(<span style="color: #0000ff;">"c651f5f6-1c0d-492e-8ae1-b4efd7c9d503"</span>);<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000; font-weight: bold;">using</span>&nbsp;(EventTraceWatcher watcher =&nbsp;<span style="color: #008b8b; font-weight: bold;">new</span>&nbsp;<span style="color: #191970; font-weight: bold;">EventTraceWatcher</span>(<span style="color: #0000ff;">"WcfErrors"</span>,&nbsp;RewriteProviderId))<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watcher.EventArrived&nbsp;+=&nbsp;<span style="color: #ff0000;">delegate</span>(<span style="color: #ff0000;">object</span>&nbsp;sender,&nbsp;EventArrivedEventArgs e)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;waitForEvent.<span style="color: #191970; font-weight: bold;">Set</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;};<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008000;">// Start listening</span><br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;watcher.<span style="color: #191970; font-weight: bold;">Start</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;waitForEvent.<span style="color: #191970; font-weight: bold;">WaitOne</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #191970; font-weight: bold;">RunProcess</span>(<span style="color: #0000ff;">"PerfView.exe"</span>,&nbsp;<span style="color: #0000ff;">"stop -AcceptEULA -NoGui -logfile:perfview_stop.log"</span>);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #008080; font-weight: bold;">catch</span>&nbsp;(Exception exc)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Console.<span style="color: #191970; font-weight: bold;">WriteLine</span>(exc);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span style="color: #0000ff; font-weight: bold;">private</span>&nbsp;<span style="color: #a52a2a;">static</span>&nbsp;<span style="color: #ff0000;">void</span>&nbsp;<span style="color: #191970; font-weight: bold;">RunProcess</span>(<span style="color: #ff0000;">string</span>&nbsp;executable,&nbsp;<span style="color: #ff0000;">string</span>&nbsp;arguments)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Process process;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ProcessStartInfo startInfo;<br /> <br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process =&nbsp;<span style="color: #008b8b; font-weight: bold;">new</span>&nbsp;<span style="color: #191970; font-weight: bold;">Process</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startInfo =&nbsp;<span style="color: #008b8b; font-weight: bold;">new</span>&nbsp;<span style="color: #191970; font-weight: bold;">ProcessStartInfo</span>(executable,&nbsp;arguments);<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;startInfo.UseShellExecute =&nbsp;<span style="color: #008b8b; font-weight: bold;">false</span>;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.StartInfo = startInfo;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.<span style="color: #191970; font-weight: bold;">Start</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;process.<span style="color: #191970; font-weight: bold;">WaitForExit</span>();<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br /> &nbsp;&nbsp;&nbsp;&nbsp;}<br /> }</p>
<p>This starts PerfView with a 250MB circular buffer. The AcceptEULA and NoGui parameters are probably not necessary with the logfile parameter specified. In the middle the wait is implemented by watching the WCF ETW provider on an existing session named WcfErrors. That session must be setup prior to running this tool.</p>
<p>Here are instructions on how to create the session, which are the same as Daniel included in his blog:</p>
<ol>
<li>Open the Performance Monitor tool (should be under Administrative Tools)</li>
<li>Locate Data Collector Sets -&gt; Event Trace Sessions in the tree on the left</li>
<li>Right-click on Event Trace Sessions and picked New -&gt; Data Collector Set</li>
<li>Name the set &ldquo;WcfErrors&rdquo;, use manual setup, and hit next</li>
<li>Next to Providers, click Add and find the provider "Microsoft-Windows-Application Server-Applications"</li>
<li>Under Properties select Level and hit Edit</li>
<li>Pick win:Error and hit OK</li>
<li>Click Next twice</li>
<li>Select "Open properties for this data collector set" and hit Finish</li>
<li>Go to the Trace Session tab</li>
<li>Change the Stream mode to Realtime</li>
<li>Hit OK</li>
<li>Start the WcfErrors session</li>
</ol>
<p>With the session created you should be able to run the tool. When it finishes, PerfView will create a zip file and a summary file. If necessary PerfView will generate the NGEN PDBs and store them in a symbols folder in the zip file.</p>
<p>The only filter I apply above is on the level, which I set to Error. But you can be more specific by filtering to a certain channel and set of keywords. EventTraceWatcher unfortunately does not give you the whole event, just a dictionary of properties for the event. So if you wanted to filter in your code, then you would have to edit the EventTraceWatcher&nbsp;code to expose the rest of the event's properties.</p>]]></content:encoded>
    </item>
    <item>
      <title>TFS Power Tools Issues</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/tfs-power-tools-issues</link>
      <pubDate>Thu, 24 Jan 2013 12:24:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/01/24/tfs-power-tools-issues/</guid>
      <description><![CDATA[During a forward integration, it is helpful to get a report of what changes occurred during that...]]></description>
      <content:encoded><![CDATA[<p>During a forward integration, it is helpful to get a report of what changes occurred during that time period. This started out being done by hand but programmers hate doing by hand what should be easy to automate. There were many ways to produce the report but the easiest approach I found was to use the TFS PowerShell cmdlets in the TFS Power Tools. This allowed me to create a script that shows each change formatted the way I wanted it including a list of work items for each change. Here is the script:</p>
<p style="font-family: Courier New;"><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changesets</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">=</span><span style="color: black;">&nbsp;</span><span style="color: blue;">get-tfsitemhistory</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">.</span><span style="color: black;">&nbsp;</span><span style="color: navy;">-recurse</span><span style="color: black;">&nbsp;</span><span style="color: navy;">-Version</span><span style="color: black;">&nbsp;</span><span style="color: darkred;">"D09/01/2012~D12/31/2099"</span><span style="color: black;"><br /></span><span style="color: darkblue;">foreach</span><span style="color: black;">&nbsp;(</span><span style="color: orangered;">$changeset</span><span style="color: black;">&nbsp;</span><span style="color: darkblue;">in</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changesets</span><span style="color: black;">)<br />{<br />&nbsp;&nbsp;</span><span style="color: darkred;">"------------------------------------------------------------------------------------------------------"</span><span style="color: black;"><br />&nbsp;&nbsp;</span><span style="color: darkred;">"Changeset:&nbsp;{0}&nbsp;"</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">-f</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">ChangeSetId<br />&nbsp;&nbsp;</span><span style="color: darkred;">"Owner:&nbsp;{0}"</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">-f</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">Owner<br />&nbsp;&nbsp;</span><span style="color: darkred;">"Date:&nbsp;{0}"</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">-f</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">CreationDate<br />&nbsp;&nbsp;</span><span style="color: darkred;">""</span><span style="color: black;"><br />&nbsp;&nbsp;</span><span style="color: darkred;">"Comments:&nbsp;{0}"</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">-f</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">Comment<br />&nbsp;&nbsp;</span><span style="color: darkred;">""</span><span style="color: black;"><br />&nbsp;&nbsp;</span><span style="color: blue;">Get-TfsChangeset</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">changesetid&nbsp;</span><span style="color: darkgray;">|</span><span style="color: black;">&nbsp;</span><span style="color: blue;">select</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">changesetid</span><span style="color: black;">&nbsp;</span><span style="color: navy;">-exp</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">changes</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">|</span><span style="color: black;">&nbsp;</span><span style="color: blue;">format-table</span><span style="color: black;">&nbsp;</span><span style="color: navy;">-auto</span><span style="color: black;"><br />&nbsp;&nbsp;</span><span style="color: darkred;">"Work&nbsp;Items:"</span><span style="color: black;"><br />&nbsp;&nbsp;</span><span style="color: blue;">Get-TfsChangeset</span><span style="color: black;">&nbsp;</span><span style="color: orangered;">$changeset</span><span style="color: darkgray;">.</span><span style="color: black;">changesetid&nbsp;</span><span style="color: darkgray;">|</span><span style="color: black;">&nbsp;</span><span style="color: blue;">select</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">changesetid</span><span style="color: black;">&nbsp;</span><span style="color: navy;">-exp</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">workitems</span><span style="color: black;">&nbsp;</span><span style="color: darkgray;">|</span><span style="color: black;">&nbsp;</span><span style="color: blue;">format-table</span><span style="color: black;">&nbsp;</span><span style="color: blueviolet;">id</span><span style="color: darkgray;">,</span><span style="color: blueviolet;">title</span><span style="color: black;">&nbsp;<br />&nbsp;&nbsp;</span><span style="color: darkred;">""</span><span style="color: black;"><br />}<br />&nbsp;</span></p>
<p>After upgrading to VS2012, the script stopped working and would only report the following errors:</p>
<pre>Unable to determine the source control server.
Unable to determine the workspace.</pre>
<p>The first error message was coming from the get-tfsitemhistory command. I have more than one TFS enlistment on my machine so I figured it could be that. The command has a -server parameter so I attempted to use that by calling get-tfsserver. Get-tfsserver works just fine and is able to find the server. But get-tfsitemhistory fails with the "unable to determine the workspace" error. I've seen many possible solutions online about re-creating the workspace and connecting visual studio to the workspace but none of those worked.</p>
<p>My problem turned out to be VS2012. When you install VS2012, you need to update your TFS Power Tools. Here are the steps I followed:</p>
<ol>
<li>Open Add/Remove programs and uninstall Microsoft Team Foundation Server 2010 Power Tools</li>
<li>Go to: <a href="https://visualstudiogallery.msdn.microsoft.com/b1ef7eb2-e084-4cb8-9bc7-06c3bad9148f">https://visualstudiogallery.msdn.microsoft.com/b1ef7eb2-e084-4cb8-9bc7-06c3bad9148f</a></li>
<li>Click on download and open the msi</li>
<li>Choose custom installation and make sure that powershell cmdlets are installed</li>
</ol>]]></content:encoded>
    </item>
    <item>
      <title>The server rejected the session-establishment request</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/the-server-rejected-the-session-establishment-request</link>
      <pubDate>Thu, 24 Jan 2013 11:43:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/01/24/the-server-rejected-the-session-establishment-request/</guid>
      <description><![CDATA[Here is an interesting WCF exception you may have encountered before. In my case we were looking...]]></description>
      <content:encoded><![CDATA[<p>Here is an interesting WCF exception you may have encountered before. In my case we were looking into a performance issue for a client.</p>
<h2>Environment</h2>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2133.Environment.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2133.Environment.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/2133.Environment.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/2133.Environment.PNG" alt="" border="0" /></a></p>
<p>This setup is pretty common. A set of load-balanced web servers is talking to a load-balanced WCF middle tier. The middle tier interacts with the data source.</p>
<p>In this case, there are two WCF services: one streamed and one buffered. Both services use the net.tcp transport with binary encoding.</p>
<h2>The Problem</h2>
<p>One of the symptoms that I dread the most when diagnosing WCF issues is the CommunicationException. It's a generic catch-all that gives no information as to what actually happened. You'll usually see something like this in the diagnostics logs.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/1234.CommExc.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/1234.CommExc.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/1234.CommExc.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/1234.CommExc.PNG" alt="" border="0" /></a></p>
<p>The error message usually looks like this:</p>
<p style="font-family: courier new,courier;">&lt;Exception&gt;<br /> &nbsp;&nbsp;&lt;ExceptionType&gt;System.ServiceModel.CommunicationException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;<br /> &nbsp;&nbsp;&lt;Message&gt;The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.7348017'.&lt;/Message&gt;<br /> &nbsp;&nbsp;&lt;StackTrace&gt;...&lt;/StackTrace&gt;<br /> &nbsp;&nbsp;&lt;ExceptionString&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;System.ServiceModel.CommunicationException: The socket connection was aborted. This could be caused by an error processing your message or a receive timeout being exceeded by the remote host, or an underlying network resource issue. Local socket timeout was '00:00:59.7348017'. ---&gt; System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)<br /> &nbsp;&nbsp;&nbsp;&nbsp;--- End of inner exception stack trace ---<br /> &nbsp;&nbsp;&lt;/ExceptionString&gt;<br /> &nbsp;&nbsp;&lt;InnerException&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionType&gt;System.Net.Sockets.SocketException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;Message&gt;An existing connection was forcibly closed by the remote host&lt;/Message&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;/StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionString&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.SocketConnection.ReadCore(Byte[] buffer, Int32 offset, Int32 size, TimeSpan timeout, Boolean closing)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;/ExceptionString&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;NativeErrorCode&gt;2746&lt;/NativeErrorCode&gt;<br /> &nbsp;&nbsp;&lt;/InnerException&gt;<br /> &lt;/Exception&gt;</p>
<p>This exception can happen for a lot of reasons. So it pays to dig around the log and look for other signs of trouble. There could be other kinds of exceptions buried in there or warnings about hitting throttling limits. In our case, there was another kind of exception mixed in that WCF eats by default.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/8422.ProtocolExc.PNG" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/8422.ProtocolExc.PNG"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/41/84/8422.ProtocolExc.PNG" original-url="https://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-41-84/8422.ProtocolExc.PNG" alt="" border="0" /></a></p>
<p>You can see there is a sequence of events to this exception. After the exception is thrown, it is handled and a message is logged indicating that an attempt to reuse a pooled connection failed. The socket connection is aborted and then a retry is attempted. These exceptions are being eaten by WCF since you can see that after a couple attempts, the rest of the request continues. Note that this is coming from the client side. The exception itself looks like this:</p>
<p style="font-family: courier new,courier;">&lt;Exception&gt;<br /> &nbsp;&nbsp;&lt;ExceptionType&gt;System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;<br /> &nbsp;&nbsp;&lt;Message&gt;<span style="background-color: #ffff00;"><strong>The server at net.tcp://someserver/MyService.svc rejected the session-establishment request.</strong></span>&lt;/Message&gt;<br /> &nbsp;&nbsp;&lt;StackTrace&gt;<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionUpgradeHelper.ValidatePreambleResponse(Byte[] buffer, Int32 count, ClientFramingDecoder decoder, Uri via)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IConnection connection, TimeoutHelper&amp; timeoutHelper, ClientFramingDecoder decoder, SecurityMessageProperty&amp; remoteSecurity)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper&amp; timeoutHelper)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFramingRequest.SendRequest(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)<br /> &nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)<br /> &nbsp;&nbsp;at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)<br /> &nbsp;&nbsp;...<br /> &nbsp;&nbsp;at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()<br /> &nbsp;&nbsp;at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)<br /> &nbsp;&nbsp;at System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(Exception error)<br /> &nbsp;&nbsp;at System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)<br /> &nbsp;&nbsp;at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)<br /> &nbsp;&nbsp;at System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)<br /> &nbsp;&nbsp;&lt;/StackTrace&gt;<br /> &nbsp;&nbsp;&lt;ExceptionString&gt;System.ServiceModel.ProtocolException: The server at net.tcp://someserver/MyService.svc rejected the session-establishment request. ---&gt; System.ServiceModel.ProtocolException: <span style="background-color: #ffff00;"><strong>Error while reading message framing format at position 0 of stream (state: ReadingUpgradeRecord) ---&gt; System.IO.InvalidDataException: More data was expected, but EOF was reached.</strong></span><br /> &nbsp;&nbsp; --- End of inner exception stack trace ---<br /> &nbsp;&nbsp; --- End of inner exception stack trace ---&lt;/ExceptionString&gt;<br /> &nbsp;&nbsp;&lt;InnerException&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionType&gt;System.ServiceModel.ProtocolException, System.ServiceModel, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;Message&gt;Error while reading message framing format at position 0 of stream (state: ReadingUpgradeRecord)&lt;/Message&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionUpgradeHelper.ValidatePreambleResponse(Byte[] buffer, Int32 count, ClientFramingDecoder decoder, Uri via)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IConnection connection, TimeoutHelper&amp; timeoutHelper, ClientFramingDecoder decoder, SecurityMessageProperty&amp; remoteSecurity)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper&amp; timeoutHelper)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFramingRequest.SendRequest(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)<br /> &nbsp;&nbsp;&nbsp;&nbsp;...<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(Exception error)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)<br /> &nbsp;&nbsp;&nbsp;&nbsp;at System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;/StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionString&gt;System.ServiceModel.ProtocolException: Error while reading message framing format at position 0 of stream (state: ReadingUpgradeRecord) ---&gt; System.IO.InvalidDataException: More data was expected, but EOF was reached.<br /> &nbsp;&nbsp;&nbsp;&nbsp; --- End of inner exception stack trace ---&lt;/ExceptionString&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&lt;InnerException&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionType&gt;System.IO.InvalidDataException, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089&lt;/ExceptionType&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;Message&gt;<span style="background-color: #ffff00;"><strong>More data was expected, but EOF was reached.</strong></span>&lt;/Message&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionUpgradeHelper.ValidatePreambleResponse(Byte[] buffer, Int32 count, ClientFramingDecoder decoder, Uri via)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.SendPreamble(IConnection connection, TimeoutHelper&amp; timeoutHelper, ClientFramingDecoder decoder, SecurityMessageProperty&amp; remoteSecurity)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedConnectionPoolHelper.AcceptPooledConnection(IConnection connection, TimeoutHelper&amp; timeoutHelper)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ConnectionPoolHelper.EstablishConnection(TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.StreamedFramingRequestChannel.StreamedFramingRequest.SendRequest(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.RequestChannel.Request(Message message, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData&amp; msgData, Int32 type)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;...<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp; completedSynchronously)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.ApplicationStepManager.ResumeSteps(Exception error)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpApplication.System.Web.IHttpAsyncHandler.BeginProcessRequest(HttpContext context, AsyncCallback cb, Object extraData)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.HttpRuntime.ProcessRequestInternal(HttpWorkerRequest wr)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;at System.Web.Hosting.ISAPIRuntime.ProcessRequest(IntPtr ecb, Int32 iWRType)<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;/StackTrace&gt;<br /> &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;ExceptionString&gt;System.IO.InvalidDataException: More data was expected, but EOF was reached.&lt;/ExceptionString&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&lt;/InnerException&gt;<br />&nbsp;&nbsp;&lt;/InnerException&gt;<br /> &lt;/Exception&gt;</p>
<h2>ProtocolException</h2>
<p>When sending a message over a connection, WCF will first establish the protocol by sending a few meaningful bytes. In this case, the WCF server has both a buffered service and a streamed service. These two transfer modes use different protocols. So if a connection was created by a buffered service call, added to the connection pool upon the buffered service call's completion, and then used by a streamed service call, that could explain the ProtocolException. We thought this could occur because the client side WCF connection pool for TCP is based on IP address. Since the two services were on the same server, we believed the clients were sharing the connection pool. To test our theory, we asked the client to set the connectionGroupName attribute in their client side configuration. Setting the group name allows you to isolate the connection pools. The client tried this but observed no change in behavior. The reason for this is streamed services don't use connection pools. Something else was causing the ProtocolException.</p>
<h2>Creating a Repro</h2>
<p>As your possible solutions become more difficult to test, the best thing to do is create a small reproduction of the issue. This can be tricky to get right. Most of the WCF repros I write take into account the following characteristics of the original service:</p>
<ul>
<li>Hosting - IIS, port sharing, self-host</li>
<li>Binding - TCP, HTTP</li>
<li>Types of services -&nbsp;quick responses, I/O intensive, CPU intensive</li>
<li>Sync or async</li>
<li>Transfer modes - buffered, streamed</li>
</ul>
<p>In this case, there were both buffered and streamed, synchronous, I/O-bound (calling into a database) services using a TCP binding&nbsp;with IIS hosting (TCP and IIS implies port sharing).</p>
<p>This is the buffered service. The sleep is to simulate holding the thread while contacting the database. Usually database calls are quicker than this but sleeps like 1 or 2 seconds can help make problems easier to recreate and analyze.</p>
<script type="text/javascript" src="https://gist.github.com/4626585.js"></script>
<p>And this is the streamed service:</p>
<script type="text/javascript" src="https://gist.github.com/4626548.js"></script>
<p>Here is the configuration for the services. The custom binding used is equivalent to a nettcp binding. Using a custom binding will come in handy for trying different settings (such as the connection pool group name mentioned earlier).</p>
<script type="text/javascript" src="https://gist.github.com/4626599.js"></script>
<p>On the client side I attempt to simulate load on the service by running many parallel requests:</p>
<script type="text/javascript" src="https://gist.github.com/4626627.js"></script>
<p>The CorrelationManager.ActivityId is useful for grouping the events for a given request under unique ids. Otherwise when you look at the trace in svctraceviewer you'll see everything is grouped under the 00000 id.</p>
<p>The full solution is available at the bottom of the post.</p>
<p>When I tried running the code I initially had no luck reproducing the problem despite tweaking thread pool settings, the number of simultaneous requests, and the throttle settings on the services. So I tried a different approach and ran many client processes simultaneously using the following command line trick:</p>
<p style="font-family: courier new,courier;">for /l %i in (1,1,5) do start TestClient.exe</p>
<p>The number 5 indicates that I want the for loop to execute 5 times. When I ran this I was able to reproduce the issue and get the exact same ProtocolException in the client side logs.</p>
<h2>The Solution</h2>
<p>With the repro it is now possible to tweak settings and quickly find out what's wrong. For instance, if you just run the buffered service by itself, the issue still repros meaning that it's not the combination of the buffered and streamed service. The real difference was that multiple client processes were talking to the same service. This is entirely possible when you're dealing with an environment where multiple web servers are calling into a WCF middle tier. The problem ended up being with the connection pool settings on the services and the fix is easy.</p>
<script type="text/javascript" src="https://gist.github.com/4626787.js"></script>
<p>The service is keeping a pool of connections to the clients calling it. Also each client is keeping a pool of connections to the buffered service. By default, these two pools will be the same size. So one client and one server sending multiple simultaneous requests should work just fine. But when there are many clients, the service runs out of connections and starts closing down inactive ones. The client doesn't know the service closed the connection and only finds out when it gets the ProtocolException. That's why WCF eats the exception. The real problem was then that eventually all the connections would be active and after a client exhausted all the connections in the pool it would try to establish a new connection but the server would reject it, resulting in the CommunicationException. Bumping the maxOutboundConnectionsPerEndpoint fixed the issue.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/38/64/37/ConnectionPool.zip" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-38-64-37/ConnectionPool.zip">ConnectionPool.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Win8 computer wakes up by itself</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/win8-computer-wakes-up-by-itself</link>
      <pubDate>Sat, 05 Jan 2013 21:50:46 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2013/01/05/win8-computer-wakes-up-by-itself/</guid>
      <description><![CDATA[One night I'm working at my desk with my computer off. Suddenly my computer turns itself on. I've...]]></description>
      <content:encoded><![CDATA[<p>One night I'm working at my desk with my computer off. Suddenly my computer turns itself on. I've disabled mouse and keyboard inputs from waking it up. The only thing that should wake it from sleep is when I press the power button. Luckily there is a command that can tell you what woke your computer up. Open a command prompt and type "powercfg -lastwake". Here's what I saw:</p>
<pre>C:\Users\Dustin&gt;powercfg -lastwake
Wake History Count - 1
Wake History [0]
  Wake Source Count - 1
  Wake Source [0]
    Type: Wake Timer
    Owner: [PROCESS] \Device\HarddiskVolume1\Windows\System32\services.exe
    Owner Supplied Reason: Windows will execute 'NT TASK\Microsoft\Windows\Media Center\mcupdate_scheduled' scheduled task that requested waking the computer.</pre>
<p>So apparently I have a scheduled task called mcupdate_scheduled that woke my computer up. Next step, go to the start screen and type "scheduled" and you'll see an application called Scheduled Tasks. The path to the task is listed in the message above: Microsoft -&gt; Windows -&gt; Media Center. Navigate to that in the tree on the left and look for the mcupdate_scheduled task. If you look at the task and go to the Conditions tab you'll see that the "Wake the computer to run this task" checkbox is checked.</p>
<p>Seriously? Who in their infinite wisdom decided that Media Center update was so important that my computer needed to be woken up for it? There's even a KB article for it: <a href="https://support.microsoft.com/kb/979878">https://support.microsoft.com/kb/979878</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Azure Remote PowerShell</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/azure-remote-powershell</link>
      <pubDate>Sun, 16 Dec 2012 22:22:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2012/12/16/azure-remote-powershell/</guid>
      <description><![CDATA[This post is about how I created a utility that allows me to send PowerShell commands to a specific...]]></description>
      <content:encoded><![CDATA[<p>This post is about how I created a utility that allows me to send PowerShell commands to a specific Azure instance without the need to publicly expose a port or use Azure Connect.</p>
<p>First, I think I should explain why I did this.</p>
<p>In performance analysis, the more information you can capture, the better. Profiles, process dumps, logs, etc. are all useful pieces of information essential to finding and fixing performance problems. In a typical application performance analysis happens at the same time as the other development work, which makes it very important to automate as much as possible. For instance, the infrastructure used to performance test WCF instruments for memory, throughput, and latency and captures profiles all on a daily basis. When a regression is detected, we can instantly pull up the logs and/or profiles and do a comparison to find out what happened. I wanted to be able to achieve the same thing in my new role working on Azure applications.</p>
<p>The WCF performance lab has a private network with dedicated network hardware. We can use a tool like psexec to run commands. There is a network share available to copy logs and other files. A typical test might go something like this:</p>
<ol>
<li>Copy bits to server and client machines</li>
<li>Setup profilers and/or log collection agents on server(s)</li>
<li>Start services on the server(s)</li>
<li>Start client(s)</li>
<li>Wait for test execution to complete</li>
<li>Close profilers/log collection agents</li>
<li>Copy files from client and server machines to network share</li>
<li>Analyze results and upload to a database/website for reporting</li>
</ol>
<p>Azure gives us a new challenge in several areas: copying bits on and off the machines, starting/stopping profilers or agents, and controlling clients. When we deploy the cspkg to Azure, that is how we get bits onto the server machines. The clients are specialized roles that will download test bits from blob storage and have communication ports open to accept commands for running tests. But on the server instances we need a way to get files on and off the machines as well as send commands without changing the code that was deployed in the cspkg. We want to test that code as it would be deployed in production.</p>
<p>The solution to this starts with a <a href="https://blogs.msdn.com/b/dmetzgar/archive/2012/12/11/azure-table-storage-wcf-custom-transport-channel.aspx">previous post</a> on how to use Azure tables as a transport mechanism. This allows me to create a WCF service that does not need to open a port. The minimal impact I could think of was to add a startup task to the csdef and a few binaries to the cspkg that would start a Windows service on the Azure instance.</p>
<p>While I could create a WCF service that accepts specific commands like "iisreset" or "start test", it's not a very flexible solution. I chose to do PowerShell not only because it is very powerful but also because it allows for <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/ee706594(v=vs.85).aspx">custom hosting</a>.</p>
<p>In my code, I started with the sample linked above and made a few changes. The sample is meant to give you a custom shell that runs in a console window. It does a lot of things like change the foreground/background colors, get/set cursor positions, and gets the dimensions of the console window. All of that has to be adjusted. Also, there is an interface called IHostUISupportsMultipleChoiceSelection. If you were executing a command that asks for verification, such as for overwriting a file, the custom host can decide not to support that. In all of my Prompt methods I throw NotImplementedException. It makes the HostUserInterface class pretty simple:</p>
<script type="text/javascript" src="https://gist.github.com/4316979.js"></script>
<p>As you can see, the only thing that's really implemented here is the Write method, which just writes to a StringBuilder. I use this to capture all the output from a command. When a command is done executing, I empty the contents of the StringBuilder and pass it back in the response.</p>
<p>PSListenerConsoleSample is pretty much verbatim copied from the example. It starts the UI. In my case, I don't call the Run method, only the Execute method. The WCF service inherits from PSListenerConsoleSample:</p>
<script type="text/javascript" src="https://gist.github.com/4317017.js"></script>
<p>The DumpOutput method just gets the current string from the StringBuilder and then empties it. SendCommand takes the string in the request, executes it, and then returns the output as a response.</p>
<p>One interesting thing I noticed is that in the example, the output of a command will typically go to the console window that is running the PowerShell host. Since mine is running as a Windows service I thought I would have to find a way to redirect that output. Much to my happiness, PowerShell's code is already redirecting it and I didn't have to do anything.</p>
<p>The RawUserInterface is the last thing to make changes to. You have to replace the data it's trying to get from the Console. Here is my version:</p>
<script type="text/javascript" src="https://gist.github.com/4317099.js"></script>
<p>The buffer size I chose is 1000 wide by 9999 high. If you connect to this PowerShell with a console client, be sure to change the buffer size on the console to at least the same width.</p>
<p>The rest of the code should be pretty easy to understand if you've been following the <a href="https://blogs.msdn.com/b/dmetzgar/archive/tags/Custom+Transport+Channel/">posts</a>. There is a console client and server and a Windows service. In subsequent posts, I'll cover how to add this to an Azure role and how to get profiles.</p>
<p>The code is available here: <a href="https://github.com/dmetzgar/azure-remote-powershell">https://github.com/dmetzgar/azure-remote-powershell</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Azure table storage WCF custom transport channel</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/azure-table-storage-wcf-custom-transport-channel</link>
      <pubDate>Tue, 11 Dec 2012 17:05:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2012/12/11/azure-table-storage-wcf-custom-transport-channel/</guid>
      <description><![CDATA[Previous posts covered how to make a custom WCF transport channel that used the file system as the...]]></description>
      <content:encoded><![CDATA[<p>Previous posts covered how to make a custom WCF transport channel that used the file system as the transport mechanism. This post covers how to use Azure tables as the transport.</p>
<p>The full code is available here: <a href="https://github.com/dmetzgar/azure-table-transport">https://github.com/dmetzgar/azure-table-transport</a></p>
<p>The genesis of this transport channel came about while I was trying to find a suitable way to communicate with individual Azure instances that did not require an open port and did not go through the load balancer. There are a number of approaches that could work but the technique of communicating through Azure tables was something another group in Microsoft was doing and had success with.</p>
<p>From the service side, here is the design:</p>
<ul>
<li>The service runs on an Azure role instance</li>
<li>Deployment id, role name, and instance name are acquired from RoleEnvironment and concatenated to create a partition key for the Azure table</li>
<li>The service polls the Azure table with the partition key looking for messages</li>
<li>When a message is received, it is executed and the response is sent to another Azure table</li>
</ul>
<p>The client works in&nbsp;a similar way where it writes a request message to an Azure table and polls another table for a response. The difference is that it has to be pointed to a particular Azure role instance.</p>
<p>Turning this into a WCF transport channel seems a piece of cake when modifying the existing custom transport channel code that uses the file system.</p>
<p>The code below is using Azure SDK 1.8. The first thing I created was a TableEntity to store the SOAP message. This works for both the request and response.</p>
<script type="text/javascript" src="https://gist.github.com/4264006.js"></script>
<p>The URI for the service endpoint should serve as the name of the Azure table. Since I have two tables, I append Request and Reply to them. The ChannelListener seems a good place to create the tables if they do not already exist.</p>
<script type="text/javascript" src="https://gist.github.com/4264105.js"></script>
<p>The lynchpin of the whole system is the code to poll for messages. As with the file transport channel, both the request and reply channel classes inherit from a common base class. This is where I've added the WaitForMessage method.</p>
<script type="text/javascript" src="https://gist.github.com/4264175.js"></script>
<p>The partitionKey is stored as a member variable. You can see where it's applied as a filter condition when querying the table. The sleep value is passed in to the method. You could make this configurable if you want.</p>
<p>Writing a message to a table is the same for both request and reply.</p>
<script type="text/javascript" src="https://gist.github.com/4265858.js"></script>
<p>The code here uses the encoder (which is set to the text encoder) to write the message to a buffer created by the buffer manager. Then it's encoded as a UTF8 string. If you were to open the table in a tool like Azure Storage Explorer you would see the text SOAP message. This can help for debugging purposes.</p>
<p>Reading the message is split into two methods. This is because there are two code paths for getting the message. In the reply channel, WaitForRequest only returns a Boolean indicating whether or not a request was received within the timeout. The other path is TryReceiveRequest in the reply channel and the Request method in the request channel that waits for the reply message. This path will use the message read from the WaitForMessage method instead of reading again from the table.</p>
<script type="text/javascript" src="https://gist.github.com/4265907.js"></script>
<p>Notice also that the table entity is deleted in the finally. This is to keep us from reading the same messages over and over. You could modify this to update a flag indicating the message was read so you could keep an archive of the messages.</p>
<p>The rest of the code is pretty similar to the file transport channel. One improvement is that there are several properties added to the BindingConfigurationElement that are used in the app.config. That code is fairly straightforward as well.</p>
<p>To test this you should have the Azure SDK 1.8 installed. Start up the Storage Emulator first. Then set multiple startup projects on the solution and start the service above the client. It should work the exact same way as the file transport channel did in previous posts.</p>]]></content:encoded>
    </item>
    <item>
      <title>Adding application config for custom transport channel</title>
      <link>https://docs.microsoft.com/archive/blogs/dmetzgar/adding-application-config-for-custom-transport-channel</link>
      <pubDate>Fri, 07 Dec 2012 16:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Dustin Metzgar]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/dmetzgar/2012/12/07/adding-application-config-for-custom-transport-channel/</guid>
      <description><![CDATA[The custom transport channel has been configured in code only so far. In order to make it...]]></description>
      <content:encoded><![CDATA[<p>The custom transport channel has been configured in code only so far. In order to make it configurable via app/web.config, there are a few additions required. This post covers how to add those.</p>
<p><a href="https://blogs.msdn.com/b/dmetzgar/archive/tags/custom+transport+channel/">Click here</a> to see all the posts in this series. All the code is now available on github here: <a href="https://github.com/dmetzgar/custom-transport-channel">https://github.com/dmetzgar/custom-transport-channel</a></p>
<p>Adding a configuration element is relatively simple. The file transport is easier to work with because it has no configuration options. Handling custom configuration is handled in a later post. Add a new file to the library project called FileTransportBindingConfigurationElement, this will hold two classes: the configuration element and the collection element. The collection element is just one line, so I prefer to just put it in the same class file an the configuration element.</p>
<script type="text/javascript" src="https://gist.github.com/4237648.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>Notice that this really doesn't do much except identify the FileTransportBinding as the BindingElementType.</p>
<p>The next step is to update the FileTransportBinding to read from a configuration section. To do this, we add another constructor that takes a string and reads the FileTransportBindingCollectionElement out of the configuration section.</p>
<script type="text/javascript" src="https://gist.github.com/4237707.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>Starting from the service side, add an app.config and put in the following serviceModel section.</p>
<script type="text/javascript" src="https://gist.github.com/4237714.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>The bindingExtensions collection is what allows WCF to load the custom binding element. Since there are no configuration options, the binding just needs a name and to be assigned to an endpoint. The address is specified on the endpoint so it no longer needs to be in the&nbsp;main method. That simplifies the code for Program.cs down to this:</p>
<script type="text/javascript" src="https://gist.github.com/4237740.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>On the client side, we have to add another constructor to the ReverseClient proxy that can read from config.</p>
<script type="text/javascript" src="https://gist.github.com/4237749.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>Then add an app.config to the client with the following.</p>
<script type="text/javascript" src="https://gist.github.com/4237752.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>The same bindingExtension is added here on the client side. We do have some timeouts we can configure that are universal. This simplifies the main method of the client down to this:</p>
<script type="text/javascript" src="https://gist.github.com/4237762.js">// <![CDATA[

// ]]]]><![CDATA[></script>
<p>And that's it!</p>]]></content:encoded>
    </item>
  </channel>
</rss>