<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Casey the .NET Consultant</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/feed.xml</link>
    <description />
    <lastBuildDate>Wed, 17 Apr 2019 03:20:27 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Use node.js without the tynnary of express</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/use-node-js-without-the-tynnary-of-express</link>
      <pubDate>Fri, 10 Feb 2012 11:54:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2012/02/10/use-node-js-without-the-tynnary-of-express/</guid>
      <description><![CDATA[Using node.js without the tyranny of express and jade. 


For some reason I've still been...]]></description>
      <content:encoded><![CDATA[<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="1110601908"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">Using node.js without the tyranny of express and jade.</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="1239209629"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">For some reason I've still been obsessed with node.js, and you can read about my first impressions in my previous blog post <a title="here" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2012/01/13/my-first-impressions-of-node-js.aspx" target="_blank">here</a>. I'm not quite sure why I've had this little love affair with node.js; after all it's an interpreted language that uses JavaScript on the server - something I'm not quite sure even makes sense. My buddies tell me I shouldn't continue this torrid affair with node.js and that my one true love .NET is waiting for me at home. Everyone is correct. However, but for those of you who have a twitch and want to play with node.js a little, one of the things you may be having a hard time with is getting to know node.js's best friend. Express. In fact, all the walkthroughs I've been on just assume you're using express and they make sure you have it installed. I was annoyed. BUT THEN I discovered o</span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">ne of the very best websites I've been to that really describes the process of getting node.js up and running. <a title="http://nodebeginner.org/" href="http://nodebeginner.org/" target="_blank">http://nodebeginner.org/</a>. This site goes step by step in showing how the whole process works from beginning to end. Starts with just getting it to display hello world, and then walks though the process of creating routers, the server scripts, everything. Once you're done you can *really* see what node.js is doing when it's doing what it's doing.</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="1245039977"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">Except for how to display HTML pages.</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="41005556"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">Now toward the end of the walkthrough, there are HTML pages being displayed but it's basically in-line code. Not something you're going to want to do in a real word situation. It looks like this:</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="2030845422"><span style="font-family: verdana,geneva; font-size: small;"><span class="TextRun SCX74662680" xml:lang="EN-US">function start(response) { <br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">console.log("Request handler 'start' was called.");</span><span class="EOP SCX74662680"> <br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">var body = '&lt;html&gt;'<br />&nbsp;&nbsp; +</span><span class="TextRun SCX74662680" xml:lang="EN-US">&nbsp;'&lt;head&gt;'<br />&nbsp;&nbsp; + </span><span class="TextRun SCX74662680" xml:lang="EN-US">'&lt;meta http-equiv="Content-Type" content="text/html; '<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ 'charset=UTF-8" /&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;/head&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;body&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;form action="/upload" method="post"&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;textarea name="text" rows="20" cols="60"&gt;&lt;/textarea&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;input type="submit" value="Submit text" /&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;/form&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;/body&gt;'<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">+ '&lt;/html&gt;';<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">response.writeHead(200, {"Content-Type": "text/html"});<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">response.write(body);<br />&nbsp;&nbsp; </span><span class="TextRun SCX74662680" xml:lang="EN-US">response.end();<br /></span><span class="TextRun SCX74662680" xml:lang="EN-US">}</span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="1044758020"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">Now, Express will handle this all for you. Basically you can create a views folder, put your jade formatted markup in there, and express will display it for you. Jade? Oh yeah, that's a friend of Express who tags along. Thus far, I haven't been able to find a way to say 'Hey, Express... can we do our thing without Jade hanging around? Can we just have our fun with HTML?' Apparently not. So with all that then, there is a way to just display HTML pages. Make sure you're including fs.</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">fs = require('fs');</span><span class="EOP SCX74662680"> </span></span></div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680"><span style="font-family: verdana,geneva; font-size: small; text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">&nbsp;</span></div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680"><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">Then, you can display it like so:</span><span class="EOP SCX74662680"> </span></span></div>
<p style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680"><br /><span style="font-family: verdana,geneva; font-size: small;"><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">function start(response) {<br />&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">console.log("Request handler 'start' was called.");<br />&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">var filename = 'view/start.html';<br />&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">fs.readFile(filename, "binary", function(err, file) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">if(err) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.writeHead(500, {"Content-Type": "text/plain"});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.write(err + "\n");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.close();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">return;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">}<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.writeHead(200, {"Content-Type": "text/html"});<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.write(file, "binary");<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">response.end();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">});<br /></span><span style="text-decoration: none;" class="TextRun SCX74662680" xml:lang="EN-US">}</span></span></p>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" paraid="1606941005"><span style="font-family: verdana,geneva; font-size: small;"><span class="TextRun SCX74662680" xml:lang="EN-US">So.... tada! Now, you can use clientside JavaScript, and all the other static-like HTML you want to use!</span><span class="EOP SCX74662680"> </span></span></p>
</div>
<div style="text-indent: 0px; margin-left: 0px;" class="OutlineElement Ltr SCX74662680">
<p style="width: auto; height: auto; text-align: left; color: windowtext; text-indent: 0px; font-family: 'Segoe UI',Tahoma,Verdana,'Sans-Serif'; font-size: 8pt; font-style: normal; font-weight: normal; margin-right: 23px; vertical-align: baseline; background-color: transparent;" class="Paragraph SCX74662680" xml:lang="EN-US" paraid="241519817"><span style="font-family: verdana,geneva; font-size: small;" class="TextRun SCX74662680" xml:lang="EN-US">Now, in all honesty, you should be using some sort of engine. Without it, you are missing out on a lot of work that a lot of people have already done for you. The ability to inject content server side, for instance is helpful in creating powerful sites using node js. The <a title="github page for node" href="https://github.com/joyent/node/wiki/modules#wiki-web-frameworks-full" target="_blank">github page for node</a> lists all kind of frameworks you can use instead of Express if you prefer. So if your like me and you want to do as much as you can without a framework, and then grumble and start using one, hopefully this information is helpful.</span></p>
</div>]]></content:encoded>
    </item>
    <item>
      <title>My First Impressions of node.js</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/my-first-impressions-of-node-js</link>
      <pubDate>Fri, 13 Jan 2012 16:09:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2012/01/13/my-first-impressions-of-node-js/</guid>
      <description><![CDATA[Over the holiday season, I thought it might be fun to try the node.js on azure walkthrough here. Up...]]></description>
      <content:encoded><![CDATA[<p>Over the holiday season, I thought it might be fun to try the node.js on azure walkthrough <a title="https://www.windowsazure.com/en-us/develop/nodejs/tutorials/getting-started/" href="http://blogs.msdn.com/controlpanel/blogs/posteditor.aspx/here">here</a>. Up until recently I never even heard of node.js, but lately it&rsquo;s been all the rage so I figure I owe it to myself (and my customers) to be up to date with it. So here we go. First off, what is node.js? The quick answer to that is its server-side JavaScript. With all the JQuery, and Ajax going on, it seems like the next logical step is to push JavaScript onto the server and stick with one language. If you&rsquo;re feeling a little squeamish after reading that, then you&rsquo;re not alone. There are so many servers out there, why do you need another one?</p>
<p>Well, one of the cool things about node.js is that it is the smallest looking server I&rsquo;ve basically ever worked with. Smaller then Apache. In a few lines of code you have your entire webserver there ready to accept requests. That part is nice and powerful. If you want a longer explanation&nbsp; of node.js itself there are some <a href="http://radar.oreilly.com/2011/07/what-is-node.html">here</a>, and <a href="http://www.ibm.com/developerworks/opensource/library/os-nodejs/index.html">here</a>. Seriously, read those explanations.&nbsp;</p>
<p>Granted, I may not have really given it a good honest try, but i&nbsp; can already tell I don't really like it. I expected at first i would just be able to write an HTML and javascript/Ajax page and then just ask node to host it, adding in server side code to go with the Ajax. But noooo, apparently you need to design the pages in something called Jade, and then have something called Express&nbsp;translate the pages. Now it reminds me of Ruby or Grails. I'm sure there are other interpreters then Jade/Express, but&nbsp;I have a feeling it's going to be another thing i have to learn anyway. I guess that's my biggest gripe so far.</p>
<p>Troubleshooting is the other issue I have with node.js. As i was going through the examples from the node on azure walkthrough, and on the node.js website,&nbsp;I would occasionally make some silly mistake. Maybe i didn't close a paren, or mixed some capitalization, but in either case the only error I would get is a page telling me there was a 500 error. I had no idea where the problem was. The js? My jade/express? Was a file in the wrong folder? No idea, i just had to comment things out until things worked again and then slowly get the new changes working. Hugely annoying. Some sort of message would be nice. I realize the language isn't compiled, but still.</p>
<p>With those things, I have a hard time finding a good reason to use node.js. Especially with the learning curve. I'll find a reason though! Sometimes when you have a hammer like this, you need to find a nail. :)</p>
<p>Part of the reason I wanted to learn some node.js was because Microsoft made it easy to put onto Azure, which is handy and a load of fun! All of the tooling to get settings, create the necessary files, and publish your project is all done through Powershell. Notepad and the command line is all you need. Like I mentioned already though, I have mixed emotions doing it this way.</p>
<p>The benefit to having node.js on Azure, is its lightweight, and you'll probably be able to do more with a smaller VM size - saving you some money. Also it was actually pretty simple to get a full node.js solution up and running on Azure. I don't know if it's going to be much easier to get it going on a stand alone server. Plus once your traffic grows, and you need more power, all you'll need to do is either increase the size of your instance, or increase the amount of instances. No additional configuration will be needed. That's going to be a whole lot nicer then your typical on premise server and you have to migrate it onto a bigger server later.</p>
<p>Don't let my lackluster review of node.js prevent you from trying it out yourself. Its a popular framework right now and it may solve a problem you have. In fact if it IS solving a problem you have, let me know in the comments, I'd be excited to hear about it.</p>]]></content:encoded>
    </item>
    <item>
      <title>My review of the AT&amp;T Elevate 4G Hotspot</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/my-review-of-the-att-elevate-4g-hotspot</link>
      <pubDate>Wed, 02 Nov 2011 13:01:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/11/02/my-review-of-the-att-elevate-4g-hotspot/</guid>
      <description><![CDATA[So the location I&rsquo;m working at doesn&rsquo;t have a functioning internet connection....]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">So the location I&rsquo;m working at doesn&rsquo;t have a functioning internet connection. That&rsquo;s a problem for me. Aside from going to MSDN and checking web mail which is important for my job, I need to check traffic, news sites, occasionally social networking, and so much more. Fortunately I can do all of that easily from my Windows Phone 7, but there&rsquo;s nothing like viewing it from the comfort of your laptop. Besides that, I&rsquo;ve always been dying to break the reliance on finding a Starbucks for their WiFi. In any case it was time to find some wireless internet. I assumed I&rsquo;d do a dongle or aircard, but I discovered MiFi.</span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">Since I was already an AT&amp;T customer, I figured I&rsquo;d just continue with them. I thought about going to Sprint&rsquo;s 4G, but I heard they were dropping their WiMax for LTE. (</span><a href="http://www.wired.com/gadgetlab/2011/10/sprint-lte-rollout-2013/"><span style="color: #0000ff; font-family: Calibri; font-size: small;" size="3" face="Calibri" color="#0000ff">http://www.wired.com/gadgetlab/2011/10/sprint-lte-rollout-2013/</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">) Since LTE must obviously be the technology to use. Since AT&amp;T does 4G LTE, my decision was made. I went into the store, and their newest 4G MiFi was the Elevate. The coolest thing about the Elevate is you don&rsquo;t need to connect it to your computer to use it. You basically turn it on, and it exposes a SSID you can connect to. In fact, you can connect 5 devices to it, so I can configure my phone to connect to it also. It needs to be charged so you *eventually* need to plug it in.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">So now that I got it, how did it compare to real life usage? Pretty darn good. The first thing I did when I got it, was to do a speed test. The results were surprising. 24.03 Mb/s down, 9.79 Mb/s up, and a 49ms ping time. Amazing! I did all the stuff I normally do, lots of remote desktop, msdn, checking some news sites, all that junk. Also Outlook, Lync, and Live Mesh were running in the background syncing like they do. It&rsquo;s also interesting to note that I only have 1 bar of signal with the 4G LTE.</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/01/43/01/6082.SpeedTest.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6082.SpeedTest.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/01/43/01/6082.SpeedTest.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6082.SpeedTest.png" width="300" height="120" /></a></span></span></p>
<p><span style="font-family: Calibri; font-size: small;" size="3" face="Calibri">To really get a good idea of what it can do, I watched a streaming video demonstrating how to write and use Reactive Extensions. (</span><a href="http://msdn.microsoft.com/en-us/data/gg577609"><span style="color: #0000ff; font-family: Calibri; font-size: small;" size="3" face="Calibri" color="#0000ff">http://msdn.microsoft.com/en-us/data/gg577609</span></a><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">). I didn&rsquo;t experience a single hiccup. At this point I&rsquo;m sold.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">The only problem I experienced is one morning I turned it on, and it wasn&rsquo;t using 4G LTE. Only the 4G. I thought this would be fine, but it was not. No No No NO. When it was on normal 4G, I was getting speeds of 1.48 Mb/s down, and .71 Mb/s up with a 105ms ping time. Unacceptable. This was with 4 bars of connectivity in 4G. I was a little concerned at this point that there might not be the LTE available where I&rsquo;m at (inside an office building) all the time, and I&rsquo;d have to constantly fall back to the crappier 4G. What I did, was turn the device off and then back on again, which gave me the LTE back. If I&rsquo;m able to do that every time it drops to regular 4G, then that&rsquo;s not a problem - just an inconvenience. Hopefully I don&rsquo;t have to do that all that often.</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/01/43/01/6165.SpeedTest2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6165.SpeedTest2.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/01/43/01/6165.SpeedTest2.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6165.SpeedTest2.png" width="300" height="120" /></a></span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">As far as battery life goes, I give it a 3/5 in my mythical system where this is the only device that&rsquo;s been judged. What I was hoping for would be I could connect it, throw it into my bag, and I&rsquo;d have 4G LTE internet wherever I go until I go to bed. Then I&rsquo;d plug it in. Sadly, that&rsquo;s not the case. On a full charge, it got me though about 6 hours of my work day before the 15% alarm went off. Still that&rsquo;s not bad.</span></span></p>
<p><span style="font-size: small;" size="3"><span style="font-family: Calibri;" face="Calibri">All in all, I&rsquo;d definitely recommend it for anyone who wants super-fast wireless 4G LTE internet wherever they go.</span></span></p>]]></content:encoded>
    </item>
    <item>
      <title>A Unity Hello World Example</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/a-unity-hello-world-example</link>
      <pubDate>Fri, 08 Jul 2011 12:07:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/07/08/a-unity-hello-world-example/</guid>
      <description><![CDATA[Unity is crazy helpful framework developed by the patterns and practices group, but it&rsquo;s a...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: Calibri;" face="Calibri">Unity is crazy helpful framework developed by the patterns and practices group, but it&rsquo;s a little hard to understand how to set it up, and where exactly it can be useful. I&rsquo;m going to try in this blog to set up something super simple so you can get a good understanding of what the basic minimum is to get Unity going.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">What Unity basically does, is provide an easy solution for dependency injection. With dependency injection, you can specify in a config file, which type of a class you want to instantiate without having to maintain different versions of solution, or rebuild. I&rsquo;m going to start with a simple business scenario.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">You are in charge of an inventory system for your company, and they have two locations. One is a simple where house where they maintain a small set of inventory items in SQL Server Express. The other is a larger one where the data is stored in Azure Tables. Other than that, the application is exactly the same. Just work with me on that one.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">So, now as a developer, you need to program in two different ways of getting a hold of inventory data. To do this, we&rsquo;re going to create an interface to represent the *very* crude operations our application will use to get data. Let&rsquo;s start by creating a new C# console app. Call it &ldquo;UnityHelloWorld&rdquo;, and then create an Interface called IInventoryDataSource.</span></p>
<p><code class="csharp">namespace UnityHelloWorld<br /> {<br />&nbsp;&nbsp;&nbsp; public interface IInventoryDataSource<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InventoryItem LookupInventoryItem(int id);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;InventoryItem&gt; GetAllItems();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string GetSourceName();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void AddInventoryItem(InventoryItem item);<br />&nbsp;&nbsp;&nbsp; }<br /> }</code></p>
<p><span style="font-family: Calibri;" face="Calibri">Great! Now, let&rsquo;s go ahead and create two classes - One that will get the data from the SQL Server Express, and the other that will connect to Azure. We will put them in a folder called &ldquo;Sources&rdquo;. We won't actually connect them to the database or Azure, maybe we will address that in another blog post but for this example, we just want to get everything wired up.</span></p>
<p><br /><code class="csharp">namespace UnityHelloWorld.Sources<br />{<br />&nbsp;&nbsp;&nbsp; class SQLExpressSource : IInventoryDataSource<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public InventoryItem LookupInventoryItem(int id)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new NotImplementedException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;InventoryItem&gt; GetAllItems()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new NotImplementedException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string GetSourceName()<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "SQL Express";<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /> <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void AddInventoryItem(InventoryItem item)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throw new NotImplementedException();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp; }<br />}</code></p>
<p><br /><span style="font-family: Calibri;" face="Calibri">The Azure class is basically the same thing except for the GetSourceName() method returns "Azure Source".</span></p>
<p><code class="csharp">public string GetSourceName()<br /> {<br />&nbsp;&nbsp;&nbsp; return "Azure Source";<br /> }</code></p>
<p><span style="font-family: Calibri;" face="Calibri">Now we have two different classes and they do the same things but in very different ways. As a developer, if we wanted to create this application for the different locations, we need to figure out how to use the class we want. Our options are:</span></p>
<p><span style="font-family: Calibri;" face="Calibri">1) Create an application for the Azure Data location, and another for the small SQL Express location.<br />2) Make it configurable so they can pick a location.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">Now the first option might be great, except then we would have to maintain different versions. This is a horrible idea, but in the past I've done it. I remembering having two separate solutions, and the application did basically the same thing. I'd throw one onto a flash drive, and give it to the small shop up the road, and then install the other one on the web server at the big site. The biggest problem was always if there is a change, you need to fix it in both versions. Let&rsquo;s never do it like this again.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">Option #2 is a much better option than number one. You would create a field in app.config and set the environment you're in, and then write code to read that and instantiate the right class. It ends up looking something like this:</span></p>
<p><code class="csharp">if (configSetting == "Azure")<br />{<br /> Sources.AzureSource az = new Sources.AzureSource();<br /> // do stuff......<br />}<br />if(configSetting == "SqlExpress")<br />{<br /> Sources.SQLExpressSource ex = new Sources.SQLExpressSource();<br /> //do stuff...<br />}</code></p>
<p><span style="font-family: Calibri;" face="Calibri">You can see how that gets hairy. What if we add a third data source? Or remove one? Besides, you need to either do this in every class that accesses data, or you need to create some Factory that creates it. In fact the basic factory pattern could help in that case. </span><a href="http://www.dofactory.com/Patterns/PatternAbstract.aspx"><span style="font-family: Calibri;" face="Calibri">http://www.dofactory.com/Patterns/PatternAbstract.aspx</span></a><span style="font-family: Calibri;" face="Calibri">.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">Let&rsquo;s do this in Unity instead. What Unity will let us do is use the interface to help us construct the class we need without having to hard code the class that gets used. I'll show you what I mean.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">If you haven't already, go to the codeplex site and download the Unity. </span><a href="http://unity.codeplex.com/"><span style="font-family: Calibri;" face="Calibri">http://unity.codeplex.com/</span></a><span style="font-family: Calibri;" face="Calibri">. Once you've got that, lets create an xml file to configure how Unity will work.</span></p>
<p><code class="html">&lt;?xml version="1.0" encoding="utf-8" ?&gt; <br /> &lt;configuration&gt;<br />&nbsp;&nbsp; &lt;configSections&gt;<br />&nbsp;&nbsp;&nbsp; &lt;section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" /&gt;<br />&nbsp;&nbsp; &lt;/configSections&gt;<br />&nbsp;&nbsp; &lt;unity&gt;<br />&nbsp;&nbsp;&nbsp; &lt;typeAliases&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- First comes the typeAlias, that lets us refer to UnityHelloWorld.IInventoryDataSource as just IInventoryDataSource --&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;typeAlias alias="IInventoryDataSource" type="UnityHelloWorld.IInventoryDataSource, UnityHelloWorld" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Followed by Aliases for the sources--&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;typeAlias alias="AzureSource" type="UnityHelloWorld.Sources.AzureSource, UnityHelloWorld" /&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;typeAlias alias="SQLExpressSource" type="UnityHelloWorld.Sources.SQLExpressSource, UnityHelloWorld" /&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/typeAliases&gt;<br />&nbsp;&nbsp;&nbsp; &lt;containers&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;container name="containerOne"&gt; &lt;!-- You can call the container anything you like. --&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;types&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;!-- Type mapping using aliases defined above --&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;type type="IInventoryDataSource" mapTo="SQLExpressSource" /&gt; &lt;!-- The mapTo here lets us select which will get Resolved at runtime. --&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/types&gt;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/container&gt;<br />&nbsp;&nbsp;&nbsp; &lt;/containers&gt;<br />&nbsp;&nbsp; &lt;/unity&gt;<br /> &lt;/configuration&gt;</code></p>
<p><span style="font-family: Calibri;" face="Calibri">Now let&rsquo;s go back to our Program.cs, and add some using files for unity, and to get a hold of our xml file:</span></p>
<p><code class="csharp">using System.Configuration;<br />using Microsoft.Practices.Unity;<br />using Microsoft.Practices.Unity.Configuration;</code></p>
<p><span style="font-family: Calibri;" face="Calibri">...and now let&rsquo;s add some code to wire up the config file with unity...</span></p>
<p><code class="csharp">IUnityContainer container = new UnityContainer();<br /> <br />ExeConfigurationFileMap map = new ExeConfigurationFileMap();<br />map.ExeConfigFilename = "unity.config";<br />Configuration config = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);<br />UnityConfigurationSection section = (UnityConfigurationSection)config.GetSection("unity");<br />section.Containers["containerOne"].Configure(container);</code></p>
<p><br /><span style="font-family: Calibri;" face="Calibri">These&nbsp;6 lines of code basically say "go get the unity.xml files, and set up unity to use it." And now that we have Unity all configured, let&rsquo;s use it!</span></p>
<p><span style="font-family: Calibri;" face="Calibri">To mimic "using" unity at this point, we are going tell it we want a new IInventoryDataSource, and it will be of whatever type that we configured in the unity.xml file. If you notice in the xml files, we've told it to map to the "SQLExpressSource". Here's the one line of code that does that:</span></p>
<p><code class="csharp">IInventoryDataSource ds = container.Resolve&lt;IInventoryDataSource&gt;();</code></p>
<p><span style="font-family: Calibri;" face="Calibri">Now, in that one line, we never actually tell it what Class we are going to instantiate. We did that in the config file. As you would imagine, if we call the GetSourceName() method on ds, it will return "SQL Express" - which is what we coded in the class. Though Unity, we basically did this:</span></p>
<p><code class="csharp">IInventoryDataSource ds = new Sources.SQLExpressSource();</code></p>
<p><span style="font-family: Calibri;" face="Calibri">That's freaking cool.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">If we wanted to switch it to the Azure source, all we need to do is change the xml file. If we built a new source, like FlatFileDataSource or OracleDataSource, as long as it implemented IInventoryDataSource, we can add it to the xml file, and choose to have that instantiated instead. The great benefit to this is we don't have to dig through code and find the old instances and replace it with new ones.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">There we go! Hopefully you can see the power and simplicity of using Unity in your application. More and more developers are starting to use this as a way of storing connection strings, as well and configuring development, test, and production server environments.</span></p>
<p><span style="font-family: Calibri;" face="Calibri">Can you see a use for it with the project you're working on? Would you like to see it actually connected to Azure?</span> <span style="font-family: Calibri;" face="Calibri">Let me know! I've </span><a title="attached the project" href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/7128.UnityHelloWorld.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/7128.UnityHelloWorld.zip"><span style="font-family: Calibri;" face="Calibri">attached the project</span></a><span style="font-family: Calibri;" face="Calibri"> for you to download and see.</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Extention Methods and the Principal of Single Responsibility</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/extention-methods-and-the-principal-of-single-responsibility</link>
      <pubDate>Sat, 04 Jun 2011 16:38:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/06/04/extention-methods-and-the-principal-of-single-responsibility/</guid>
      <description><![CDATA[Recently I was handed a solution I needed to do some refactoring on, everything was good except...]]></description>
      <content:encoded><![CDATA[<p>Recently I was handed a solution I needed to do some refactoring on, everything was good except their user data was now coming from a different source. Originally, they were pulling it down from active directory and then putting most of the fields into a new class called User. Okay, good. Now, they were going to be getting user data out of a database and the fields weren&rsquo;t exactly the same. Also, there was a change they were going to be getting the occasional user data from an old Oracle database as well. Don&rsquo;t ask. Either way, I now had three classes with basically the same information. Here were some of the field differences.</p>
<p>SSN/SocialSecirityNumber/Social<br />Username/username/UserName<br />Birthdate/DOB/dateOfBirth (all in different date formats)</p>
<p>Ugh.</p>
<p>The application itself was used to this &lsquo;User&rsquo; object, and was basically programmed to use those fields. When it wanted to get the SSN, it would use objectname.SSN, and when it wanted to calculate the age of the user it used objectname.Birthdate in the equation. Now there are a variety of ways we can integrate the new data sources into the application.</p>
<p>One of the ways is to go into each class, and to add another field where the getter/setter pulls the other field. For example if I go into the class that pulls the Oracle data&hellip;</p>
<pre class="scroll"><code class="csharp">public string Social { get; set; }<br />
public string SSN<br />{
   get { return this.Social;  }
   set { this.Social = value; }
}
</code></pre>
<p>&nbsp;And then do this for all the different Classes. This is not the way you should do it. The class that gets the values from the database/active directory/wherever is doing its job of getting those values. They&rsquo;re probably named like that in the database. Adding more fields or (the other thing that you thought of doing) adding a conversion method would break the <a href="http://www.objectmentor.com/resources/articles/srp.pdf" title="Principal of Single Responsibility">Principal of Single Responsibility</a>. This class is getting data from the source.</p>
<p>So we likely need a separate class that represents the data, and moves it around two whichever object needs it. A Data Transfer Object if you will. Since the application is designed to accept fields from the original Active Directory store, we can match those fields.</p>
<pre class="scroll"><code class="csharp">public class UserDTO
{
    public string Name { get; set; }
    public string SSN { get; set; }
    public DateTime DOB { get; set; }
    /* more fields... */
}</code></pre>
<p>&nbsp;Now, we can change the application to use this object instead of the old User class it was used to. That modification isn&rsquo;t that time consuming. So now we have a new UserDTO object, and we feel better because it doesn&rsquo;t rely on the old User object that was based on Active Directory. Now we need to get the data from the data sources into the DTO. One of the things we could do is create conversion methods in the DTO. While this would work, it again violates the principal that a class should be only doing one thing. Plus, if we did that, this is how we would use it.</p>
<pre class="scroll"><code class="csharp">public void DoStuff()
{
    DatabaseUser dbUser = new DatabaseUser();
    UserDTO user = UserDTO.ConvertFromDatabase(dbUser);
}</code></pre>
<p>Not bad&hellip; notice how we have a DatabaseUser object (assume it came with data), then we created a UserDTO object and ran the conversion method to give us a NEW UserDTO object with values.</p>
<p>There&rsquo;re really not anything wrong with this method, except it will require us to write conversion methods for the other types. What if we wanted to convert from a UserDTO to its old type? What if we needed this DTO in another part of the solution that doesn&rsquo;t use/need/care about the old types? This DTO sure will carry a lot of baggage&hellip;</p>
<p>ENTER THE EXTENSION METHOD</p>
<p>So Extension Methods are basically static methods that attach themselves onto a parent class, without actually being in the parent class. Or as <a href="http://msdn.microsoft.com/en-us/library/bb383977.aspx" title="MSDN ">MSDN</a> explains it: &ldquo;Extension methods enable you to "add" methods to existing types without creating a new derived type, recompiling, or otherwise modifying the original type.&rdquo; That&rsquo;s our winner right there. Let&rsquo;s create an extension method to handle the conversion&hellip;</p>
<pre class="scroll"><code class="csharp">namespace Extensions
{
    public static class UserExtensions<br />
    {
        public static SomeSolution.UserDTO ToUserDTO(this SomeSolution.DatabaseUser dbUser)
        {
            return new SomeSolution.UserDTO { Name = dbUser.Name, SSN = dbUser.SocialSecurityNumber, DOB = DateTime.Parse(dbUser.DateOfBirth) };
        }
    }
}</code></pre>
<p>We plopped this in a new namespace, but you don&rsquo;t necessarily need to do that. Also, the method is a public static method. Okay. So it looks like the conversion method that we had before. So&hellip; here&rsquo;s the cool part.</p>
<p>&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/6835.extention1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6835.extention1.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/6835.extention1.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6835.extention1.png" border="0" /></a></p>
<p><span style="font-family: verdana,geneva; font-size: small;">Ah-ha! There is our extension method there! The conversion is done in a whole &lsquo;nother class where we can manage it outside of the original class. Perfect.</span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">Also, cool? Extension methods can extend the functionality of the String class. Remember, the String class is &lsquo;sealed&rsquo; meaning it can&rsquo;t be derived from (subclassed) but with Extension methods, we can add some extra functionality to strings! So look what I can do with our SSN..</span><span style="font-family: verdana,geneva; font-size: small;">&nbsp;</span></p>
<pre class="scroll"><code class="csharp">public static System.String ToSNFormat(this string ssn)
{
    return String.Format("{0}-{1}-{2}", ssn.Substring(0, 3), ssn.Substring(3, 2), ssn.Substring(5, 4));
}</code></pre>
<p><span style="font-family: verdana,geneva; font-size: small;">Now, when we go and look at the options for our SSN field&hellip;</span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">&nbsp;</span></p>
<p><span style="font-family: verdana,geneva; font-size: small;"><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/6557.ToSSNFormat.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6557.ToSSNFormat.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/6557.ToSSNFormat.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-43-01/6557.ToSSNFormat.png" border="0" /></a></span><span style="font-family: verdana,geneva; font-size: small;"></span></p>
<p><span style="font-family: verdana,geneva; font-size: small;">Boo-ya!</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Logging Your Application for Fun and Profit Part 3</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/logging-your-application-for-fun-and-profit-part-3</link>
      <pubDate>Wed, 16 Feb 2011 21:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/02/16/logging-your-application-for-fun-and-profit-part-3/</guid>
      <description><![CDATA[In Parts 1 and 2, I discussed the importance of logging your application and a few different ways of...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: verdana,geneva;">In <a title="Parts 1" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2011/02/15/logging-your-application-for-fun-and-profit-part-1.aspx">Parts 1</a> and <a title="Part 2" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2011/02/15/logging-your-application-for-fun-and-profit-part-2.aspx">2</a>, I discussed the importance of logging your application and a few different ways of doing it. The whole time though, we focused on logging errors, however errors aren't the only thing that needs to be logged. Often you'll want an idea of what's going on inside the application. What data is it getting back? What are the values? Sometimes these things can be helpful. Previously, we discussed the idea of having a static method called LogError, it looked a lot like this:</span></p>
<p><span style="font-family: verdana,geneva;"><br />
<pre class="scroll"><code class="cplusplus">public static void LogError(string message)<br />{<br />    Console.WriteLine("ERROR: " + message);<br />    Debug.Write(message, "DeathRayControllerERROR");<br />    if (!EventLog.SourceExists("DeathRayController"))<br />    {<br />        EventLog.CreateEventSource("DeathRayController", "Application");<br />    }<br />    EventLog.WriteEntry("DeathRayController", "ERROR: " + message, EventLogEntryType.Error);<br />    WriteToLogFile("ERROR: " + message);<br />}</code></pre>
</span></p>
<p><br />This is great for logging and capturing Errors - things that may have crippled or stopped our application. Let&rsquo;s add some additional methods to our class to long things that are not errors:</p>
<p><span style="font-family: verdana,geneva;">
<pre class="scroll"><code class="cplusplus">public static void logDebug(string message)<br />public static void logInfo(string message)<br />public static void logWarning(string message)</code></pre>
</span></p>
<p><br />So many options! But why? Well, to give you the level of logging you want. We have Info, Debug, Warning, and Error now. Each of these can be used to log your application depending on what you need to see. Debug will generally be used for logging everything you could possibly want to know including queries, users accessing the application, and lengths of time things take to execute.&nbsp; Info can be used when you want a good idea of what&rsquo;s going on, but don&rsquo;t want the entire granularity from Debug. Warning is generally used for things that you might be concerned about, but doesn&rsquo;t generally effect the application running at this moment.<br />I&rsquo;ve re-written the IsDeathRayTempOkay() method to use some more logging&hellip;</p>
<p><span style="font-family: verdana,geneva;">
<pre class="scroll"><code class="cplusplus">private bool IsDeathRayTempOkay()<br />{<br />    //Since we don't have an ACTUAL death ray (yet), lets simulate some conditions...<br />    try<br />    {<br />        Random rnd = new Random(DateTime.Now.Millisecond);<br />        int action = rnd.Next(0, 25);<br />        Logger.LogDebug("Death Ray Temp is: " + action);<br />        if (action &lt;= 5)<br />        {<br />            Logger.LogError("Death Ray is too hot, please wait for cooling.");<br />            return false;//Death Ray is too hot! Can't use!<br />        }<br />        if (action == 13)<br />        {<br />            throw new DeathRayOutOfMemoryException(); //Weird exception we dont handle...<br />        }<br />    }<br />    catch (DeathRayOutOfMemoryException)<br />    {<br />        Logger.LogError("Exception Thrown! Death Ray is out of memory!");<br />        return false;<br />    }<br />    Logger.LogInfo("Temp is okay to fire Death Ray...");<br />    return true;<br />}</code></pre>
</span></p>
<p><br />Notice now we have a few LogInfo, and LogDebug statements in there. Remember, you&rsquo;re deciding what is getting logged and at what level. When you start the application, you select which levels you&rsquo;re going to see.&nbsp; If you&rsquo;re going to set it to &ldquo;Info&rdquo;, for instance, you&rsquo;ll see all the logging that&rsquo;s occurred at Info, Warning, and Error. Setting it to Warning will give you all the logging at Warning and Error.<br />I&rsquo;ve written statements to set my level of logging, and I configure them in the constructor of the DeathRayController class. You can set them up in a helper class, a config file, or whatever you want to use to support it. Here&rsquo;s how I set mine up:</p>
<p><span style="font-family: verdana,geneva;">
<pre class="scroll"><code class="cplusplus">Logger.IsEnabled = true;<br />Logger.WriteToDbgViewEnabled = true;<br />Logger.WriteToEventLogEnabled = true;<br />Logger.WriteToFileEnabled = false;<br />Logger.SetDetailToDebug();<br />Logger.ApplicationName = "DeathRayController";</code></pre>
<br />When I&rsquo;m writing applications, I almost always use the logging class. It doesn&rsquo;t take a lot to set up and can be a lifesaver when something goes wrong. I've included below the entire class I&rsquo;ve been using so you can use it, modify it, whatever. What do you think? Is something missing? Have you used it? If so, did you like it?<br /></span></p>
<p><span style="font-family: verdana,geneva;">
<pre class="scroll"><code class="csharp">class Logger<br />{<br />    private static int logLevel; //a numerical representation of the log level.<br />    public static bool IsEnabled { get; set; } //when using this class, this will turn on and off the logging.<br />    <br />    public static bool WriteToFileEnabled { get; set; } //Turn on/off writing to the file<br />    private static string filePath; //if you're turning on writing to a file, you'd better set this path also!<br />    <br />    public static bool WriteToDbgViewEnabled { get; set; } //Turn on/off DbgView...<br />    public static bool WriteToEventLogEnabled { get; set; } //Tuen on/off Event Logging....<br /><br />    public static string ApplicationName { get; set; }<br /><br />    //Default Constructor. Since this Class will not be instansinated, no reason to make it a public constructor.<br />    private Logger() { }<br /><br />    /**<br />	 This function writes to the console whatever is passed into it.<br />	 In this function, it checks to see if enabled is false, or if the log level is outside of range.<br />	 If either of those condtiions are true, the function will not print the message.<br />	 logLevel can be only be 0 for this to print.<br />	 */<br />     public static void LogDebug(string message)<br />     {<br />         if (IsEnabled == false || logLevel &gt; 0)<br />         {<br />             return;<br />         }<br />         Console.WriteLine("DEBUG: " + message);<br />         WriteToLogFile("DEBUG: " + message);<br />         WriteToDbgView("DEBUG: " + message);<br />         WriteToEventLog("DEBUG: " + message, EventLogEntryType.Information);<br />     }<br /><br />     /**<br />     This function writes to the console whatever is passed into it.<br />     In this function, it checks to see if enabled is false, or if the log level is outside of range.<br />     If either of those condtiions are true, the function will not print the message.<br />     logLevel can be either 0 or 1.<br />     */<br />     public static void LogInfo(string message)<br />     {<br />         if (IsEnabled == false || logLevel &gt; 1)<br />         {<br />             return;<br />         }<br />         Console.WriteLine("INFO: " + message);<br />         WriteToLogFile("INFO: " + message);<br />         WriteToDbgView("INFO: " + message);<br />         WriteToEventLog("INFO: " + message, EventLogEntryType.Information);<br />     }<br /><br />     /**<br />     This function writes to the console whatever is passed into it.<br />     In this function, it checks to see if enabled is false, or if the log level is outside of range.<br />     If either of those condtiions are true, the function will not print the message.<br />     logLevel can be either 0, 1, or 2.<br />     */<br />     public static void LogWarning(string message)<br />     {<br />         if (IsEnabled == false || logLevel &gt; 2)<br />         {<br />             return;<br />         }<br />         Console.WriteLine("WARNING: " + message);<br />         WriteToLogFile("WARNING: " + message);<br />         WriteToDbgView("WARNING: " + message);<br />         WriteToEventLog("WARNING: " + message, EventLogEntryType.Warning);<br />     }<br /><br />     /**<br />     This function writes to the console whatever is passed into it.<br />     In this function, it checks to see if enabled is false, or if the log level is outside of range.<br />     If either of those condtiions are true, the function will not print the message.<br />     Note: When logging is enabled, this will ALWAYS print.<br />     */<br />     public static void LogError(string message)<br />     {<br />         if (IsEnabled == false || logLevel &gt; 3)<br />         {<br />             return;<br />         }<br />         Console.WriteLine("ERROR: " + message);<br />         WriteToLogFile("ERROR: " + message);<br />         WriteToDbgView("ERROR: " + message);<br />         WriteToEventLog("ERROR: " + message, EventLogEntryType.Error);<br />     }<br /><br />     public static void SetPath(string path)<br />     {<br />         filePath = path;<br />     }<br /><br />     /**<br />     This function will allow you to maunally set the logging level.<br />     The value can be set to 0, 1, 2, or 3. If you go outside the acceptable levels, <br />     this function will set it to the closest acceptable level. <br />     0: Debug<br />     1: Info<br />     2: Warning<br />     3: Error<br />     Alternatively, the built-in methods for setting the logLevels can be used.<br />     */<br />     public static void SetLogLevel(int level)<br />     {<br />         //Logging can come in 4 different levels:<br />         //	0: Debug<br />         //	1: Info<br />         //	2: Warning<br />         //	3: Error<br />         logLevel = level;<br />         if (level &lt; 0) { logLevel = 0; }<br />         if (level &gt; 3) { logLevel = 3; }<br />     }<br /><br />     public static int SetLogLevel() { return logLevel; }<br /><br />     /**<br />     Built-in method for setting the logLevel to 0 (Debug).<br />     */<br />     public static void SetDetailToDebug() { SetLogLevel(0); }<br /><br />     /**<br />     Built-in method for setting the logLevel to 1 (Info).<br />     */<br />     public static void SetDetailToInfo() { SetLogLevel(1); }<br /><br />     /**<br />     Built-in method for setting the logLevel to 2 (Warning).<br />     */<br />     public static void SetDetailToWarning() { SetLogLevel(2); }<br /><br />     /**<br />     Built-in method for setting the logLevel to 3 (Error).<br />     */<br />     public static void SetDetailToError() { SetLogLevel(3); }<br /><br />     private static void WriteToLogFile(string message)<br />     {<br />         if (WriteToFileEnabled == false) { return; }<br />         System.IO.StreamWriter file =  null;<br />         if (filePath == null)<br />         {<br />             Console.WriteLine("FilePath must be set in order to write to logs.");<br />             return;<br />         }<br />         try<br />         {<br />             file = new System.IO.StreamWriter(filePath, true);<br />             file.WriteLine(message + "\n");<br />         }<br />         catch (System.IO.PathTooLongException)<br />         {<br />             Console.WriteLine("A PathTooLongException occured. Maybe try shortening the path, buddy.");<br />         }<br />         catch (System.IO.IOException iox)<br />         {<br />             Console.WriteLine("An IOException occured. Something is wrong with my ability to write the file.\n" + iox.ToString());<br />         }<br />         catch (Exception ex)<br />         {<br />             Console.WriteLine("Writing to the file failed. Here's what happened:");<br />             Console.WriteLine();<br />             Console.WriteLine(ex.ToString());<br />         }<br />         finally<br />         {<br />             if (file != null)<br />             {<br />                 file.Close();<br />             }<br />         }<br />     }<br /><br />     private static void WriteToDbgView(string message)<br />     {<br />         if (WriteToDbgViewEnabled == false) { return; }<br />         try<br />         {<br />             Debug.Write(message, ApplicationName == null ? ApplicationName : "");<br />         }<br />         catch (Exception ex) { } //Failed...<br />     }<br /><br />     private static void WriteToEventLog(string message, EventLogEntryType eventType)<br />     {<br />         if (WriteToEventLogEnabled == false) { return; }<br />         try<br />         {<br />             EventLog.WriteEntry(ApplicationName == null ? ApplicationName : "", message, eventType);<br />         }<br />         catch (Exception ex) { } //Failed...<br />     }<br />  }</code></pre>
</span></p>]]></content:encoded>
    </item>
    <item>
      <title>Logging Your Application for Fun and Profit Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/logging-your-application-for-fun-and-profit-part-2</link>
      <pubDate>Tue, 15 Feb 2011 17:39:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/02/15/logging-your-application-for-fun-and-profit-part-2/</guid>
      <description><![CDATA[Back in Part1, I discussed logging using dbgview, here in Part 2, I'll move into the EventLog and as...]]></description>
      <content:encoded><![CDATA[<p>Back in <a title="Part 1" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2011/02/15/logging-your-application-for-fun-and-profit-part-1.aspx">Part1</a>, I discussed logging using dbgview, here in Part 2, I'll move into the EventLog and as a developer, I <b>despise </b>the event log. it's hard to get to, and 
isn't as user friendly as it should be. I mentioned already that Admins 
LOVE the event log mostly because they have many tools set up to 
monitor it and be alerted if something isn't working. This has it's 
benefits. Say for instance, that our DeathRayController also connects to
 a SQL server. Now if the SQL server goes down, our application <i>may </i>fail
 in some way, and that failure <i>will </i>be logged to the event logger. Administrators will know the extent our application is effected by this outage immediately, and they don't have to find out on their own. I've 
been around projects where the SQL server will run out of space, or a 
change is made and it goes down. Then everyone is opening up 
applications and websites to see if it's down too. Did it connect to 
that server? Is it even affected? If it didn't write to the event log, then it should be good. No phone calls to you while you're sleeping/watching American Idol. Lets write to the event log.</p>
<h3>Writing to the Event Log</h3>
<p>Instructions on how to write to the event log are here: 
<a title="here" href="http://support.microsoft.com/kb/307024">http://support.microsoft.com/kb/307024</a>, so lets use that to add a line 
to our method and write to the event log also:</p>
<pre class="scroll"><code class="csharp">class Logger<br />{<br />    public static void LogError(string message)<br />    {<br />        Console.WriteLine("ERROR: " + message);<br />        Debug.Write(message, "DeathRayControllerERROR");<br />        if (!EventLog.SourceExists("DeathRayController"))<br />        {<br />            EventLog.CreateEventSource("DeathRayController", "Application");<br />        }<br />        <br />        EventLog.WriteEntry("DeathRayController", "ERROR: " + message, EventLogEntryType.Error);<br />    }<br />}</code></pre>
<p>Here we are checking to see if the DeathRayController exists as a 
source, and if not, we create it (the source is really just the name of the application.) Then... We write to it, and specify that
 it should go into the event log as an error. Easy-peasy (yeah I went there). If we run this, and pull 
open the event log, we can see the entries in there.</p>
<p><img src="http://blogs.msdn.com/controlpanel/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-01/6305.eventviewer.png" border="0" /></p>
<p>There we see an error, when it occured, the source is our DeathRayController. There is an event ID also, and it's optional when writing to the event log. We could use that if we like to give a numerical error to our error, this way we don't have to read the contents. 1 could mean a SQL problem, 2 could mean a memory error, 739 could mean someone had installed the death ray backwards. It's really up to you. I didn't specify an event id.</p>
<p>If we look at one of the errors int he event log, we can see the details of the error we logged...</p>
<p><img src="http://blogs.msdn.com/controlpanel/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-01/8662.eventerror.png" border="0" /></p>
<p>&nbsp;</p>
<p>There is pleanty of room for LOTS of text here, so when writing to the event log, feel free to really add the information you need in there. </p>
<p>Like I said, the event log really isn't for debugging as much as it is for logging, and it's more of an admin thing then a developer tool. It's so easy though to write to it, you might as well just do it. It's great 
for administrators who are used to being in there, and there are 3rd party tools that monitor the event log, like <a title="EventSentry" href="http://www.eventsentry.com/">EventSentry</a>, or <a title="LogRhythm" href="http://www.logrhythm.com/">LogRhythm</a>, that can help parse those things out.</p>
<p>Now, event logging is good for things that have HAPPENED, and writing to the event log is good for administrators, but annoying for developers. You know what works fairly decently for developers? Writing to a text file.</p>
<h3>A Simple Text File</h3>
<p>The best things about text files, is their really, really simple, and
 if you have access to the application folder, you can look at the text 
file (probably). The problem with text files, is you might not have the 
ability write to the folder, system IO problems, and the size of the 
text file. Generally, if you DO write to a text file, you'll want to 
create a new file based on the date, and you'll want to throw it all in a
 try/catch in case you're getting more errors then you can successfully 
write. Here is a method that writes errors to the file...</p>
<pre class="scroll"><code class="csharp">private static void WriteToLogFile(string message)<br />{<br />     //set the path to something you can write to...<br />     string filePath = string.Format(@"C:\DeathRayControllerLog_{0}-{1}-{2}.txt", DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day);<br />     System.IO.StreamWriter file = null;<br />     if (filePath == null)<br />     {<br />         Console.WriteLine("FilePath must be set in order to write to logs.");<br />         return;<br />     }<br />     try<br />     {<br />         file = new System.IO.StreamWriter(filePath, true);<br />         file.WriteLine(message + "\n");<br />     }<br />     catch (System.IO.PathTooLongException)<br />     {<br />         Console.WriteLine("A PathTooLongException occured. Maybe try shortening the path, buddy.");<br />     }<br />     catch (System.IO.IOException iox)<br />     {<br />         Console.WriteLine("An IOException occured. Something is wrong with my ability to write the file.\n" + iox.ToString());<br />     }<br />     catch (Exception ex)<br />     {<br />         Console.WriteLine("Writing to the file failed. Here's what happened:");<br />         Console.WriteLine();<br />         Console.WriteLine(ex.ToString());<br />     }<br />     finally<br />     {<br />         if (file != null)<br />         {<br />             file.Close();<br />         }<br />     }<br />}<br /></code></pre>
<p>Then we simply add another item to our method...</p>
<p>&nbsp;</p>
<pre class="scroll"><code class="csharp">public static void LogError(string message)<br />{<br />     Console.WriteLine("ERROR: " + message);<br />     Debug.Write(message, "DeathRayControllerERROR");<br />     if (!EventLog.SourceExists("DeathRayController"))<br />     {<br />         EventLog.CreateEventSource("DeathRayController", "Application");<br />     }<br />     EventLog.WriteEntry("DeathRayController", "ERROR: " + message, EventLogEntryType.Error);<br />     <span style="background-color: #ffff99;">WriteToLogFile("ERROR: " + message);</span><br /> }</code></pre>
<p>Notice in the WriteToLogFile class, I catch a bunch of different exceptions,<b> this is 
important</b>! You don't want your logging to cause even MORE errors then 
the application already has. Writing to a text file can cause all sorts of problems with security, naming, the file already being opened, the file being gone, etc. It's best to just catch and ignore then introduce more problems. However if everything is working well, having a generic text file to see errors can be immensely helpful, especially if your logging more then just 
errors. Thats right MORE THEN JUST ERRORS! I'll talk about other types of logging in <a title="Part 3" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2011/02/17/logging-your-application-for-fun-and-profit-part-3.aspx">Part 3</a>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Logging Your Application for Fun and Profit Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/logging-your-application-for-fun-and-profit-part-1</link>
      <pubDate>Tue, 15 Feb 2011 09:33:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/02/15/logging-your-application-for-fun-and-profit-part-1/</guid>
      <description><![CDATA[When writing applications, I often have a good idea about what
it's supposed to be doing when it's...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">When writing applications, I often have a good idea about what
it's supposed to be doing when it's running, after all I wrote/helped write the
darn thing. But once you start adding WCF services, databases, authentications,
and other things not controlled directly by you, it's hard to make sure the
program you wrote is working like you intended it to. Was the WCF call
successful? Was the database authenticated successfully? Naturally, if your
application is working then everything is doing what you programed it to. But
when it's not - and there will be times it doesn't - it's good to know where
the problem lies, and what caused it.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">In the past, I've had several instances when I was sitting
at my desk and someone would come over and say "Casey! Your death ray
controller application is down!" in which I would proceed to spend time
debugging the application to find out why it all of a sudden wasn't working
when it used to. Maybe the database is down... maybe the host machine ran out of
resources... maybe there was a change to a server that caused one of my
components to break. It was usually something odd. But the problem wasn't that
it broke, the problem was the length of time it took to find what the problem
was. "What do you mean you have no idea?!" They would say. "You WROTE the
program!"</span></span></p>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">Soon I learned that adding some logging to the application
can QUICKLY shorten the time it takes to determine what the problem is. It also
helps to give you some piece of mind that the application is running, so you
can feel comfortable handing the application off to someone else.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">There are a couple of different ways of logging your application,
and a couple of different situations in which you should do the logging. For
logging you have: Event Logs, DebugView, text file, web page, and console.
Event Logs are the least helpful to other programmers, but most helpful to
admins. The opposite is true for DebugView. Text files, web pages, and the
console works good also for some cases and can be a helpful way to check the
status of your application.</span></span></p>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">So let's make a class called "DeathRayController", and do
some logging against it...</span></span></p>
<p>&nbsp;</p>
<pre class="scroll"><code class="csharp">class DeathRayController<br />{<br />    public DeathRayController() { }<br />    public void Zap()<br />    {<br />        if (IsDeathRayConnected() == true &amp; IsDeathRayTempOkay() == true)<br />        {<br />            Console.WriteLine("ZZZZZAAAAAPPPPPP!!!!");<br />        }<br />    }<br />    <br />    private bool IsDeathRayTempOkay()<br />    {<br />        //Since we don't have an ACTUAL death ray (yet), lets simulate some conditions...<br />        Random rnd = new Random(DateTime.Now.Millisecond);<br />        int action = rnd.Next(0, 20);<br />        if (action &lt;= 5) { return false; } //Death Ray is too hot! Can't use!<br />        if (action == 13) { throw new DeathRayOutOfMemoryException(); } //Weird exception we dont handle...<br />        return true;<br />    }<br /><br />    private bool IsDeathRayConnected()<br />    {<br />        //again, no death ray, so lets simulate some conditions.<br />        Random rnd = new Random(DateTime.Now.Millisecond);<br />        int action = rnd.Next(0, 20);<br />        if (action == 5 | action == 7 | action == 14) { throw new UnableToConnectToDeathRayException(); } //unable to connect!<br />        return true;<br />    }<br />}<br /><br />public class UnableToConnectToDeathRayException : Exception { }<br />public class DeathRayOutOfMemoryException : Exception { }</code></pre>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">...and then we run through it 10 times...</span></span></p>
<pre class="scroll"><code class="csharp">static void Main(string[] args)<br />{<br />   DeathRayController dr = new DeathRayController();<br /><br />   for (int i = 0; i &lt; 10; i++) //Lets use the Death Ray 10 times!<br />   {<br />      dr.Zap();<br />      Console.WriteLine();<br />      System.Threading.Thread.Sleep(1000); //Just wait a bit...<br />   }<br />}<br /></code></pre>
<p><span style="font-family: verdana,geneva;"><span style="font-size: small;">Now
 when we run this, a few things can happen. We could see a console 
output ZZZZZAAAAAPPPPPP!!!!, or we can see nothing, or we throw an 
exception.</span></span></p>
<p><span style="font-family: verdana,geneva;">If
 this is a console application, we can just display the problem on the 
console, and hope then when it's run, someone will see this. If it's a 
service though (death ray service?), nobody will get to see a console, 
or maybe it's run on a remote machine somewhere that's not always 
monitored (on the moon!)</span></p>
<p><span style="font-family: verdana,geneva;"></span></p>
<p><span style="font-family: verdana,geneva;">This is when logging comes in handy.</span></p>
<p><span style="font-family: verdana,geneva;"></span></p>
<p><span style="font-family: verdana,geneva;">Let us create a logging class, something that we can use for... logging.</span></p>
<p>&nbsp;</p>
<pre class="scroll"><code class="csharp">class Logger<br />{<br />   public static void LogError(string message)<br />   {<br />       Console.WriteLine("ERROR: " + message)<br />&nbsp;  }<br />}<br /><br /></code></pre>
<p><span style="font-size: small;"><span style="font-family: verdana,geneva;">Then,
 we can alter our DeathRayController class to take advantage of the 
logging, here I've altered the IsDeathRayTempOkay class...</span></span></p>
<pre class="scroll"><code class="csharp">private bool IsDeathRayTempOkay()<br />{<br />     //Since we don't have an ACTUAL death ray (yet), lets simulate some conditions...<br />     try<br />     {<br />         Random rnd = new Random(DateTime.Now.Millisecond);<br />         int action = rnd.Next(0, 20);<br />         if (action &lt;= 5)<br />         {<br />             <span style="background-color: #ffff99;">Logger.LogError("Death Ray is too hot, please wait for cooling.");</span><br />             return false;//Death Ray is too hot! Can't use!<br />         }<br />         if (action == 13)<br />         {<br />             throw new DeathRayOutOfMemoryException(); //Weird exception we dont handle...<br />         }<br />     }<br /><br />     catch (DeathRayOutOfMemoryException)<br />     {<br />         <span style="background-color: #ffff99;">Logger.LogError("Exception Thrown! Death Ray is out of memory!");</span><br />     }<br /><br />     return true;<br />}</code></pre>
<p>&nbsp;</p>
<p>I've highlighted the area of my code when we access our logger. 
Again, it's only going to log to the console. But that's okay for now...
 lets see this thing in action...</p>
<p><img src="http://blogs.msdn.com/controlpanel/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-01/1884.output.png" border="0" /></p>
<p>&nbsp;</p>
<p>Okay! now we see how our our logger is logging to the console... Lets expand it a little bit, and write to the DebugView.</p>
<h3>What the heck is the DebugView?</h3>
<p>Debug view is part of the SysInternals that you can download from technet <a name="http://technet.microsoft.com/en-us/sysinternals/bb896647.aspx">here</a>.
 The benefit to DebugView, is you can write to the debugger and it will 
display live on the DebugView application. No need for the console, and 
you can access it from a different machine! Let's alter our class so we 
can take advantage of the DebugView application.</p>
<p>First, we need to add a reference to
</p>
<pre class="scroll"><code class="csharp">System.Diagnostics;</code></pre>
<p>...and then all we have to do is add a new line to our class...</p>
<pre class="scroll"><code class="csharp">public static void LogError(string message)<br />{<br />    Console.WriteLine("ERROR: " + message);<br />    <span style="background-color: #ffff99;">Debug.Write(message, "DeathRayControllerERROR");</span><br />}</code></pre>
<p>&nbsp;</p>
<p>now, if we open up DbgView, and run our application a few times, we can see the log that's produced:</p>
<p><img src="http://blogs.msdn.com/controlpanel/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-01/2502.dbgview.png" border="0" /></p>
<p>As you can see, we get all the benefits of console-like logging 
without even having a console window. Again, this works great when you 
have an application that doesn't open in a console window, or isn't 
installed on a machine that you have access to. Just like a console 
window, you can see this live as the application is running. The problem
 is, of course, it wont tell you what WAS happening, only what IS 
happening. Though the DbgView still has it benefits to being used. For 
knowing what HAS happened, you need to either write to a text file, or 
write to the event log.</p>
<p>In <a title="Part 2" href="http://blogs.msdn.com/b/casey_the_net_consultant/archive/2011/02/15/logging-your-application-for-fun-and-profit-part-2.aspx">Part 2</a>, I will discuss connecting to the Event Log...</p>]]></content:encoded>
    </item>
    <item>
      <title>United Channel 9</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/united-channel-9</link>
      <pubDate>Sat, 12 Feb 2011 10:20:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/02/12/united-channel-9/</guid>
      <description><![CDATA[Normal
  0
  
  
  
  
  false
  false
  false
  
  EN-US
  X-NONE
  X-NONE...]]></description>
      <content:encoded><![CDATA[<p><!--[if gte mso 9]><xml>
 <w:WordDocument>
  <w:View>Normal</w:View>
  <w:Zoom>0</w:Zoom>
  <w:TrackMoves />
  <w:TrackFormatting />
  <w:PunctuationKerning />
  <w:ValidateAgainstSchemas />
  <w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
  <w:IgnoreMixedContent>false</w:IgnoreMixedContent>
  <w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
  <w:DoNotPromoteQF />
  <w:LidThemeOther>EN-US</w:LidThemeOther>
  <w:LidThemeAsian>X-NONE</w:LidThemeAsian>
  <w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
  <w:Compatibility>
   <w:BreakWrappedTables />
   <w:SnapToGridInCell />
   <w:WrapTextWithPunct />
   <w:UseAsianBreakRules />
   <w:DontGrowAutofit />
   <w:SplitPgBreakAndParaMark />
   <w:EnableOpenTypeKerning />
   <w:DontFlipMirrorIndents />
   <w:OverrideTableStyleHps />
  </w:Compatibility>
  <m:mathPr>
   <m:mathFont m:val="Cambria Math" />
   <m:brkBin m:val="before" />
   <m:brkBinSub m:val="&#45;-" />
   <m:smallFrac m:val="off" />
   <m:dispDef />
   <m:lMargin m:val="0" />
   <m:rMargin m:val="0" />
   <m:defJc m:val="centerGroup" />
   <m:wrapIndent m:val="1440" />
   <m:intLim m:val="subSup" />
   <m:naryLim m:val="undOvr" />
  </m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
 <w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="true"
  DefSemiHidden="true" DefQFormat="false" DefPriority="99"
  LatentStyleCount="267">
  <w:LsdException Locked="false" Priority="0" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Normal" />
  <w:LsdException Locked="false" Priority="9" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="heading 1" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 2" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 3" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 4" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 5" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 6" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 7" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 8" />
  <w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 9" />
  <w:LsdException Locked="false" Priority="39" Name="toc 1" />
  <w:LsdException Locked="false" Priority="39" Name="toc 2" />
  <w:LsdException Locked="false" Priority="39" Name="toc 3" />
  <w:LsdException Locked="false" Priority="39" Name="toc 4" />
  <w:LsdException Locked="false" Priority="39" Name="toc 5" />
  <w:LsdException Locked="false" Priority="39" Name="toc 6" />
  <w:LsdException Locked="false" Priority="39" Name="toc 7" />
  <w:LsdException Locked="false" Priority="39" Name="toc 8" />
  <w:LsdException Locked="false" Priority="39" Name="toc 9" />
  <w:LsdException Locked="false" Priority="35" QFormat="true" Name="caption" />
  <w:LsdException Locked="false" Priority="10" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Title" />
  <w:LsdException Locked="false" Priority="1" Name="Default Paragraph Font" />
  <w:LsdException Locked="false" Priority="11" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtitle" />
  <w:LsdException Locked="false" Priority="22" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Strong" />
  <w:LsdException Locked="false" Priority="20" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Emphasis" />
  <w:LsdException Locked="false" Priority="59" SemiHidden="false"
   UnhideWhenUsed="false" Name="Table Grid" />
  <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Placeholder Text" />
  <w:LsdException Locked="false" Priority="1" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="No Spacing" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 1" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 1" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 1" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 1" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 1" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 1" />
  <w:LsdException Locked="false" UnhideWhenUsed="false" Name="Revision" />
  <w:LsdException Locked="false" Priority="34" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="List Paragraph" />
  <w:LsdException Locked="false" Priority="29" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Quote" />
  <w:LsdException Locked="false" Priority="30" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Quote" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 1" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 1" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 1" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 1" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 1" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 1" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 1" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 1" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 2" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 2" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 2" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 2" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 2" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 2" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 2" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 2" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 2" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 2" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 2" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 2" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 2" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 2" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 3" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 3" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 3" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 3" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 3" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 3" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 3" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 3" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 3" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 3" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 3" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 3" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 3" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 3" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 4" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 4" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 4" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 4" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 4" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 4" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 4" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 4" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 4" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 4" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 4" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 4" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 4" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 4" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 5" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 5" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 5" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 5" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 5" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 5" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 5" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 5" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 5" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 5" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 5" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 5" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 5" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 5" />
  <w:LsdException Locked="false" Priority="60" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Shading Accent 6" />
  <w:LsdException Locked="false" Priority="61" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light List Accent 6" />
  <w:LsdException Locked="false" Priority="62" SemiHidden="false"
   UnhideWhenUsed="false" Name="Light Grid Accent 6" />
  <w:LsdException Locked="false" Priority="63" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 1 Accent 6" />
  <w:LsdException Locked="false" Priority="64" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Shading 2 Accent 6" />
  <w:LsdException Locked="false" Priority="65" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 1 Accent 6" />
  <w:LsdException Locked="false" Priority="66" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium List 2 Accent 6" />
  <w:LsdException Locked="false" Priority="67" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 1 Accent 6" />
  <w:LsdException Locked="false" Priority="68" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 2 Accent 6" />
  <w:LsdException Locked="false" Priority="69" SemiHidden="false"
   UnhideWhenUsed="false" Name="Medium Grid 3 Accent 6" />
  <w:LsdException Locked="false" Priority="70" SemiHidden="false"
   UnhideWhenUsed="false" Name="Dark List Accent 6" />
  <w:LsdException Locked="false" Priority="71" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Shading Accent 6" />
  <w:LsdException Locked="false" Priority="72" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful List Accent 6" />
  <w:LsdException Locked="false" Priority="73" SemiHidden="false"
   UnhideWhenUsed="false" Name="Colorful Grid Accent 6" />
  <w:LsdException Locked="false" Priority="19" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Emphasis" />
  <w:LsdException Locked="false" Priority="21" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Emphasis" />
  <w:LsdException Locked="false" Priority="31" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Subtle Reference" />
  <w:LsdException Locked="false" Priority="32" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Intense Reference" />
  <w:LsdException Locked="false" Priority="33" SemiHidden="false"
   UnhideWhenUsed="false" QFormat="true" Name="Book Title" />
  <w:LsdException Locked="false" Priority="37" Name="Bibliography" />
  <w:LsdException Locked="false" Priority="39" QFormat="true" Name="TOC Heading" />
 </w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<mce:style><! 
 /* Style Definitions */
 table.MsoNormalTable
	{mso-style-name:"Table Normal";
	mso-tstyle-rowband-size:0;
	mso-tstyle-colband-size:0;
	mso-style-noshow:yes;
	mso-style-priority:99;
	mso-style-parent:"";
	mso-padding-alt:0in 5.4pt 0in 5.4pt;
	mso-para-margin-top:0in;
	mso-para-margin-right:0in;
	mso-para-margin-bottom:10.0pt;
	mso-para-margin-left:0in;
	line-height:115%;
	mso-pagination:widow-orphan;
	font-size:11.0pt;
	font-family:"Calibri","sans-serif";
	mso-ascii-font-family:Calibri;
	mso-ascii-theme-font:minor-latin;
	mso-hansi-font-family:Calibri;
	mso-hansi-theme-font:minor-latin;
	mso-bidi-font-family:"Times New Roman";
	mso-bidi-theme-font:minor-bidi;}
-->
<!--[endif]-->
</p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">So right
now I'm sitting on united flight 445 from BWI to Denver, and so far its been a
typical flight. We've just been told by Potomac departure that were cleared to
17000 ft. How could I possibly know this? Well, when you fly on united and turn
your headset to channel 9, you can hear live air traffic control. Everything
the pilots hear, you can hear. I love it! Being a pilot was one of the things i
would (and still) have wanted to do. Since i don't know how to fly an airplane
- yet - listening to air traffic control is the next best thing.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">"Climbing
to 270 (27000ft), with continuous light chop."</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Flying
on united isn't the only way to get my air traffic control fix, if you visit
<a name="http://www.liveatc.net/"></a>liveatc.net, you can listen to live air traffic control from many airports and
centers all over the world. If your feeling super piloty you can even fire up
<a name="http://flightaware.com/"></a>flightaware.com, and see the live locations of planes that are in the air.
Combine that with the air traffic control your listening to, and you can be
your own air traffic controller, just without the crippling stress, and risk of
accidently killing hundreds of people.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Sometimes
when I'm sitting and programming, I like to pick an airport and listen. Usually
nothing super interesting is going on, but I find its still worth listening to.
It keeps me focused on programming, and provides me with a bit of
entertainment.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Climbing
to 360. Woot! We will probably stay here for a while, as this is probably our
cruising altitude. The pilot also asked how the ride up ahead was, and ATC said
they had no reports of problems. Boring. But I'm on the boring flight, and
boring is good.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Also, if
your not familiar with listening to ATC, once you're outside of the airport,
your flight is asked to change frequencies to a regional center. These centers
basically monitor the traffic in their area, once you leave the area, your
flight is passed to another center. Once you get close to landing, you're
passed to that airport.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Now that
were cruising, the drinks are coming out. I'll take them up that.</span></p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;">Next
time your flying united, I definitely suggest listening. If you've listened
before, have you heard anything interesting? Why do you listen?</span></p>
<p class="MsoNormal">&nbsp;</p>
<p class="MsoNormal"><span style="font-size: 12pt; line-height: 115%;"><img style="border: 0pt none;" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/43/01/7318.Photo_3C9CCE41-39E6-5556-BF69-D0F5CC56A124.jpg" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-01-43-01/7318.Photo_5F00_3C9CCE41_2D00_39E6_2D00_5556_2D00_BF69_2D00_D0F5CC56A124.jpg" width="394" height="524" /><br /></span></p>]]></content:encoded>
    </item>
    <item>
      <title>Welcoming Myself to Blogging</title>
      <link>https://docs.microsoft.com/archive/blogs/casey_the_net_consultant/welcoming-myself-to-blogging</link>
      <pubDate>Fri, 21 Jan 2011 09:45:00 GMT</pubDate>
      <dc:creator><![CDATA[Casey Kriutzfield]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/casey_the_net_consultant/2011/01/21/welcoming-myself-to-blogging/</guid>
      <description><![CDATA[As a brand-spanking new employee of Microsoft, one of the first things I wanted to do was be someone...]]></description>
      <content:encoded><![CDATA[<p><span style="font-family: verdana,geneva;">As a brand-spanking new employee of Microsoft, one of the first things I wanted to do was be someone who had a blog on MSDN. The MSDN community has always been there to help guide me through some difficult programming times, as well as given me some insight into new products and technologies. Hopefully I can use this blog as a chance to give back to the programming and development community.<br /><br />As a consultant for Microsoft, I'm given a problem, and through my wizardry, I help develop a solution. Thankfully I'm not one of those super fancy consultants who identify the problem and then others to do it. The solutions I come up with i solve myself, or with a team. Generally my solutions are going to be developed in ASP.NET, MSSQL Server, sometimes using Silverlight, and sometimes on SharePoint. When I come up with a block of code, or a solution that I think might help others who are developing solutions I'll put it up here on this blog.</span></p>]]></content:encoded>
    </item>
  </channel>
</rss>