<?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>MCS UK Solution Development Team</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/mcsuksoldev/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/feed.xml</link>
    <description>The blog of the UK Solutions Development Team of Microsoft Consulting Services.</description>
    <lastBuildDate>Mon, 10 Aug 2015 12:25:13 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Why building highly scalable applications is hard – Part 2</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/why-building-highly-scalable-applications-is-hard-part-2</link>
      <pubDate>Mon, 09 Feb 2015 20:54:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2015/02/09/why-building-highly-scalable-applications-is-hard-part-2/</guid>
      <description><![CDATA[In the first part of this 2 part article I described what a Primary bottleneck is, defined what...]]></description>
      <content:encoded><![CDATA[<p>In the <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/2015/01/22/why-building-highly-scalable-applications-is-hard-part-1.aspx" target="_blank">first part</a> of this 2 part article I described what a Primary bottleneck is, defined what Latency, Throughput and Concurrency are and showed that they are entirely dependent on each other using an analogy of a pipe. In this part we’ll look at each of the core resources in current computer systems and discuss how they can affect the Latency, Throughput and Concurrency of an application.</p>  <h3>CPU utilisation</h3>  <p>CPU becomes a bottleneck at the point it becomes 100% utilised. Once you run out of spare CPU capacity, throughput and concurrency cannot increase anymore, so latency starts going up (it takes longer to get stuff done as more work is trying to share a fixed amount of CPU capacity). Historically this was resolved by making CPUs faster (reducing latency, which increases throughput). Nowadays it is more likely to be resolved by adding more CPUs (or cores) which doesn’t reduce latency but does increase concurrency and therefore throughput – assuming latency stays constant and the application can successfully distribute itself across multiple CPUs.</p>  <p>In theory each CPU core provides a concurrency of one (i.e. to process 100 concurrent operations you would need 100 CPU cores, as one core can only be processing one operation at any moment in time). However in practice this ends up not being the case because most operations don’t just need CPU and actually spend most of their time waiting for other (much slower!) resources like disk or network, which frees the CPU up to work on other things. It’s not uncommon for one CPU core to be able to handle hundreds of concurrent operations before it’s fully utilised, because over 99% of its time is spent waiting for other things to happen.</p>  <p>Making CPUs do large quantities of unnecessary work (like repeatedly executing the same compute intensive work rather than doing it once and caching it) reduces the CPUs ability to make itself free to process other operations and is a common cause of CPU bottlenecks.</p>  <p>In summary:</p>  <p>· CPU Speed determines the minimum latency.</p>  <p>· CPU utilisation determines the maximum throughput.</p>  <p>· Adding more CPU cores increases concurrency.</p>  <h3>Memory capacity and speed</h3>  <p>When memory runs out one of two things tend to happen – the application crashes or throughput falls and latency increases massively as memory is swapped out to (much slower) page files on disk. In some compute intensive applications with very low latency requirements (in the order of a few microseconds), the access time of main memory itself can start becoming a factor. However for most applications, memory is plentiful and fast and therefore rarely a bottleneck to performance – in fact caching resources in memory to avoid the higher latency or low throughput of other resources is the most common way of boosting application performance!</p>  <p>In summary:</p>  <p>· Memory access speed determines the minimum latency.</p>  <p>· Memory capacity determines the maximum throughput and concurrency.</p>  <h3>Disk throughput and latency</h3>  <p>Currently disk storage tends to be the poorest performing resource in most applications – it has the highest latency and lowest throughput of any component in a server. However it is improving all the time with the advent of Solid State Drives (SSDs) which almost eliminate the latency issues of mechanical drives (because they’re not actually drives, they’re just persistent random access memory) and generally have much better throughput as well.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/6523.clip_image002_2.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/6523.clip_5F00_image002_5F00_2.jpg"><img title="clip_image002" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" hspace="12" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/0218.clip_image002_thumb.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/0218.clip_5F00_image002_5F00_thumb.jpg" width="525" height="239" /></a></p>  <p>Mechanical hard drives are much slower than people tend to realise and many applications suffer from bad performance because of a lack of understanding of the performance characteristics of hard disks. On average the time to access any data (latency) on a mechanical drive is about 5 milliseconds (this is the average time it takes for the drive head to move to the required track on the disk platter and the disk to spin to the required point on the track) which limits a hard drives throughput to about 200 read or write requests a second. This is partially offset by the fact that if the data you need is all located in one place on the drive, then the drive head doesn’t need to move and the data can be streamed onto\off the disk at over 20Megabytes a second (which is why your PCs hard disk can stream high resolution videos without stuttering).</p>  <p>High end systems reduce these fairly severe performance limitations by grouping together several hard disks into an array and effectively treating them as a single unit by accessing them in parallel, which increases concurrency and throughput and therefore reduces the average latency.</p>  <p>In contrast, the latency of a current, enterprise class SSD is measured in microseconds, it has a throughput that can exceed over 40,000 reads\writes per second and has streaming rates that can achieve over a Gigabyte per second. Ultimately SSDs will end up as fast as main memory at which point disk performance issues will become a distant memory, but until then, and especially while mechanical drives are still around, disk will remain the slowest resource in most systems.</p>  <p>In summary:</p>  <p>· Disk seek time determines the minimum latency.</p>  <p>· Disk read\write rates determine the maximum throughput.</p>  <p>· Putting several disks in an array increases concurrency.</p>  <h3>Network throughput and latency</h3>  <p>Within data centres, network performance tends to be pretty good where the servers are locally connected and it not uncommon to obtain throughput of 1 or 10 Gigabits per second with a latency of less than 1ms. That being said, applications still want to avoid making unnecessary network round trips between servers to avoid adding too much latency. For example, many applications are guilty of making far more trips to a database server than they need to, when all the data needed could be obtained in one or two database calls, avoiding lots of unnecessary network latency and making better use of the available throughput.</p>  <p>However both throughput and latency become a much bigger deal over the internet where consumers may have poor DSL lines that only download at 1 or 2 Mbit\sec (and upload at an even lower rate!) and there is an end-to-end latency that can easily be many tens of milliseconds.</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/0753.clip_image004_2.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/0753.clip_5F00_image004_5F00_2.jpg"><img title="clip_image004" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" hspace="12" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/8130.clip_image004_thumb.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/8130.clip_5F00_image004_5F00_thumb.jpg" width="628" height="152" /></a></p>  <p>Latency tends to get overlooked when talking about networks. Just because a network has a throughput of 1Gbit\sec doesn’t necessarily mean it’s going to be fast (remember from the pipe analogy - throughput doesn’t take into account how long it takes to get through the pipe, just the rate that it comes out the end). On the internet, it’s not uncommon for a request to have to pass through several routers, and possibly a couple of firewalls on its journey between the server and the final recipient of the data. Each of these hops adds latency and it could easily take tens of milliseconds for a packet to get from one end to the other. (I’ve just pinged www.microsoft.com in the US from my desk in the UK and the request passed through 12 routers and had a roundtrip of 144ms – which means it took 72ms for my request to get to the server in the US and another 72ms to get the response back).</p>  <p>The way many websites try to reduce the effect of this high latency is by making use of the fact that often only part of the available network bandwidth (throughput) is utilised. If a browser downloads one request at a time (i.e. has a concurrency of one) it might only utilise 10% of the available throughput, so by increasing the concurrency we can more fully utilise the available throughput, which in turn reduces the average latency. This is achieved by getting the browser to make several HTTP requests simultaneously.</p>  <p>For example, say it takes 12ms to download an image from a web site and this uses 2Mbits\sec bandwidth. If we download six images one at a time then it will take a total of 72ms and use 2Mbit\sec bandwidth. If instead we download all six in parallel then, assuming we have 12Mbit\sec bandwidth available, we can now download the same six files in just 12ms. Even if the available throughput is less than 12Mbits\sec we’re still better off – say we actually only have 8Mbit\sec bandwidth available, we will make full use of our available bandwidth and we will still download all the content in around 24ms - about 1/3<sup>rd</sup> of the time compared to downloading one at a time.</p>  <p>In summary:</p>  <p>· Network bandwidth determines the maximum throughput and effective concurrency.</p>  <p>· Network length and intermediate devices determine the latency of travelling along the network.</p>  <h3>Artificial resource limits</h3>  <p>The first thing to clarify here is what exactly are “artificial resources”? These don’t necessarily have a physical manifestation but are usually software resources managed by an application which have an upper limit, or throttle, on their usage. Typical examples of these are:</p>  <p>· Locks to control concurrent access to an area of memory (e.g. critical sections, semaphores, events). These can affect throughput and latency significantly as they commonly reduce concurrency to one.</p>  <p>· Limits on the number of connections that can be made to a service (e.g. Database connections, TCP sockets).</p>  <p>· Limits on the creation of key resources (e.g. thread pools, limits on the number of active requests\transactions\operations).</p>  <p>All these artificially created throttles put a limit on the maximum concurrency that an application can support, and as we now know, if concurrency can’t increase, throughput will go down and\or latency will increase. These limits are normally in place for very good reasons: locks stop data from being corrupted. Other limits are because of design decisions (e.g. the number of possible TCP sockets is limited to 64K because it’s a 16 bit number) or are in place to protect a resource from hitting throughput limits when bad things might happen.</p>  <p>Overcoming concurrency throttling because of memory locks is generally one of the hardest of these problems to fix. It will require code changes and probably a redesign of the application to get rid of them. Often the best you can do is minimise the scope of the lock, to keep the time spent holding the lock to a minimum (reduce the locks latency and therefore increase the throughput).</p>  <p>Hard limits (like TCP sockets) are normally worked around in a couple of ways. The simplest is to scale out, to multiply the quantity of the resource available (increasing concurrency). The harder, but ultimately more efficient way, is to make better use of the available resource (e.g. reuse existing sockets rather than recycle, or put multiple sessions\requests over a single socket, which should increase throughput).</p>  <p>It’s the last case, where an artificial cap is in place to protect a resource which, in theory, should be the easiest to fix – because these limits are normally configurable and therefore all you should need to do is increase the limit until enough of the resource can be created so that it’s no longer a bottleneck. In reality it turns out that these can be some of the hardest performance issues to find, because:</p>  <p>· Often the limits are not obvious (they are system limits which you didn’t implement and aren’t even aware of), so it can be hard to find out what artificial limits even exist and what their impact is.</p>  <p>· The System doesn’t actually let you know that the limit has been hit. Commonly these limits get hit silently, with no tracing or logging being generated to indicate they have come into effect. All you know is that the performance isn’t very good for some reason. Quite often you can end up looking in the wrong place for the source of the problem, as it creates symptoms in other parts of the application that look like they might be the cause of the bottleneck, but aren’t!</p>  <p>· There are often several related limits that could be causing the problem, so even if you know which limits exist it can be hard to work out which one needs changing. (So you end up significantly increasing all of them, which gets rid of the bottleneck, but then you wonder why the limits were there in the first place…)</p>  <p>The first sign that you normally see that an artificial limit is being hit is when, regardless of what volume of traffic your application tries to process, you never hit a limit in one of the other major resources (CPU, Memory, Disk or Network) but latency gets worse as you try to increase the throughput. There is often no simple way of finding or resolving these issues other than lots of research, detective work and debugging. The ideal solution is to have good logging or monitoring which tells you that a limit is being hit and what it is.</p>  <p>In summary:</p>  <p>· Artificial limits are normally implemented by fixing the maximum concurrent access to a resource.</p>  <p>· The effect of them is that they put a cap on Throughput and therefore cause Latency to increase when that throughput limit is hit.</p>  <p>· They’re generally harder to find and fix than they should be!</p>  <h3>So why does all this matter?</h3>  <p>The fundamental problem is that the overall throughput of the solution is only as fast as the Primary Bottleneck. This can be demonstrated using our pipe analogy again. Imagine our pipe doesn’t have the same diameter along the whole of its length, but there is a narrower section in the middle…</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/5305.clip_image006_2.gif" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/5305.clip_5F00_image006_5F00_2.gif"><img title="clip_image006" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/0636.clip_image006_thumb.gif" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/0636.clip_5F00_image006_5F00_thumb.gif" width="552" height="161" /></a></p>  <p>It doesn’t matter how large the ends of the pipe are, water is only going to be able to flow from end-to-end as fast as it can get through the narrow constriction (the bottleneck!) in the middle, so the overall throughput and concurrency is going to be determined by the diameter of the narrow section, not the diameter of the end of the pipe.</p>  <p>So if an application is to have good scalability and remain responsive, every resource used by it has to be able to maintain high throughput and low latency as traffic volumes increase. The ability to stay highly responsive under load is limited by the Primary Bottleneck, but there are many things in large, complex applications which can cause bottlenecks and they all need to be understood and managed. It doesn’t matter if 99% of the execution path can support 10000 requests per second, if the other 1% only supports 10 - the application as a whole WILL only support 10 requests per second before response times start suffering and your customers start going elsewhere.</p>  <p>Finding the primary bottleneck is where performance testing comes in. You could try and guess where the primary bottleneck will be, but I can guarantee that at least 80% of the time you will guess wrong – and even if you guess right, you’ll have no idea at what level of load it’s going to start causing problems and what its impact will be. The only way to be sure where the primary bottleneck is, when it will hit and what its effect will be, is to put realistic load through the application, monitor it to see where problems start to occur and fix the problem to push the bottleneck further away. How you go about doing that will be the subject of future articles.</p>  <p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/richard+florance/default.aspx">Richard Florance</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Why building highly scalable applications is hard – Part 1</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/why-building-highly-scalable-applications-is-hard-part-1</link>
      <pubDate>Thu, 22 Jan 2015 15:16:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2015/01/22/why-building-highly-scalable-applications-is-hard-part-1/</guid>
      <description><![CDATA[In this first part of a 2 part article (click here for part 2) I’m going to discuss what causes...]]></description>
      <content:encoded><![CDATA[<p>In this first part of a 2 part article (click <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/2015/02/10/why-building-highly-scalable-applications-is-hard-part-2.aspx" target="_blank">here</a> for part 2) I’m going to discuss what causes applications to have poor performance and what you need to look at to enable them to process more work, faster and more efficiently. This discussion is relevant to ALL applications, from the smallest phone app, to the largest web site hosted on-premise or in the cloud and the biggest weather forecasting super computer.</p>  <p>The first thing to understand is that ALL applications have a <strong>Primary Bottleneck - </strong>unless you have infinite resources you can’t avoid it. The Primary Bottleneck is the first resource in an application that hits a hard limit as you increase the volume of work you want it to process. The application will normally still work after it hits this bottleneck, but any further attempt to increase the volume of work you want it to process will normally just result in the time it takes to complete the work to increase.</p>  <p>Even massive web sites, like those run by Google and Amazon, have a Primary Bottleneck. If you manage to generate enough traffic against them they will hit their Primary Bottleneck and they will slow down - they have just done a really good job of making sure that the volume of traffic required to hit the primary bottleneck is so high that you will never normally be able to reach it. To find out what the Primary Bottleneck is and to be sure it isn’t hit until the application is handling a greater volume of traffic than it needs to support in peak use, you need to undertake performance testing and analysis to find and remove as many bottlenecks as possible. This article will discuss the causes of bottlenecks, how you do the testing and analysis to find and fix bottlenecks will be the subject of some future articles.</p>  <p>To understand what causes bottlenecks and why it is actually quite hard to create highly responsive applications that can also scale to handle high volumes of work, we need to understand exactly what latency, throughput and concurrency are and how they are interdependent. We’ll define these terms by using an analogy of water flowing through a pipe:</p>  <h3>Latency</h3>  <p>Latency is a measure of how long it takes an operation to complete and is normally measured in seconds. An operation could be an http web request, a database transaction, a message or any other measurable activity – an example of latency for a web site is “It takes 200ms to load a web page”. It terms of a water pipe, it’s how long it takes the water to get from one end of the pipe to the other:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/8130.clip_image002_2.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/8130.clip_5F00_image002_5F00_2.jpg"><img title="clip_image002" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image002" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/6428.clip_image002_thumb.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/6428.clip_5F00_image002_5F00_thumb.jpg" width="540" height="196" /></a></p>  <p>Latency is affected by the length of the pipe (the shorter the pipe, the lower the latency) and the speed that the water is travelling along it (the faster the water is travelling, the lower the latency).</p>  <h3>Throughput</h3>  <p>Throughput is a measure of the rate that work can be completed and is measured in operations per second. An example of throughput for a web site is “The web site can process 500 pages per second”. Using the pipe analogy, it’s the volume of water that comes out of the end of the pipe every second:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/2642.clip_image004_2.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/2642.clip_5F00_image004_5F00_2.jpg"><img title="clip_image004" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image004" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/5238.clip_image004_thumb.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/5238.clip_5F00_image004_5F00_thumb.jpg" width="539" height="127" /></a></p>  <p>Throughput is affected by the diameter of the pipe (a wider pipe allows a greater volume of water to traverse the pipe at any moment in time) and the speed that the water travels through the pipe (the higher the speed of the water, the more water can come out of the pipe every second).</p>  <p>Hold on! We can begin to see that there is a relationship between latency and throughput - they are both affected by the speed the water travels through the pipe. The thing that ties them together and allows us to define an equation to measure this relationship is…</p>  <h3>Concurrency</h3>  <p>Concurrency is the number of operations that are being processed at any moment it time. An example of concurrency for a web site is “The Web site can process 1000 http requests simultaneously”. Using the pipe analogy, it is the volume of water that is in the pipe at any moment in time and is therefore determined by the length and diameter of the pipe:</p>  <p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/4263.clip_image006_2.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/4263.clip_5F00_image006_5F00_2.jpg"><img title="clip_image006" style="border-left-width: 0px; border-right-width: 0px; background-image: none; border-bottom-width: 0px; padding-top: 0px; padding-left: 0px; display: inline; padding-right: 0px; border-top-width: 0px" border="0" alt="clip_image006" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/3036.clip_image006_thumb.jpg" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/3036.clip_5F00_image006_5F00_thumb.jpg" width="540" height="129" /></a></p>  <p>Interesting… so Concurrency has a relationship between both Latency (affected by the length of the pipe) and Throughput (affected by the diameter of the pipe) and it turns out there is a simple equation that defines this interaction:</p>  <p><strong>Concurrency = Latency x Throughput.</strong></p>  <p>If you want to dig into this more, this is actually known as “Little’s Law” and forms part of Queueing theory. As an example of how this works, if your web site has a requirement that HTTP requests have an execution time (latency) of 0.1 seconds and maintains a throughput of 1000 requests per second, then the application must be able to process 0.1 x 1000 = 100 concurrent active requests at any moment in time. If it can’t achieve this level of concurrency then the required latency and\or throughput CANNOT be met!</p>  <p>So we now know that for our application to achieve low latency and high throughput we must also support high levels of concurrency. Let’s look at the things that effect throughput, latency and concurrency in any application using current IT technologies.</p>  <h3>Core system resources</h3>  <p>The performance characteristics of any application is ultimately defined by its use of five resources:</p>  <p>1. CPU</p>  <p>2. Memory</p>  <p>3. Disk</p>  <p>4. Network</p>  <p>5. Artificial resources</p>  <p>The maximum concurrency (and therefore throughput and latency) is going to be constrained by whichever one of these resources hits its limit first and becomes the Primary Bottleneck in the application. In the next part of this article we’ll look at each of these resources, understand what determines their latency, throughput and concurrency and talk about what we try and do to avoid them becoming a bottleneck.</p>  <p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/richard+florance/default.aspx">Richard Florance</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Access to an ASP.NET website via multiple authentications – revisited (v4.0)</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/access-to-an-asp-net-website-via-multiple-authentications-revisited-v4-0</link>
      <pubDate>Thu, 27 Nov 2014 08:44:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/11/27/access-to-an-asp-net-website-via-multiple-authentications-revisited-v4-0/</guid>
      <description><![CDATA[Hi all
A couple of years ago I posted an article entitled 'Access to an ASP.NET website via...]]></description>
      <content:encoded><![CDATA[<p>Hi all</p>
<p>A couple of years ago I posted an article entitled '<a href="http://blogs.msdn.com/b/mcsuksoldev/archive/2012/10/18/access-to-an-asp-net-website-via-multiple-authentications.aspx">Access to an ASP.NET website via multiple authentications</a>' which I advise you to read if you want to make full sense of this new post. To briefly summarise for those short of time though, consider the scenario where you have a website deployed in Azure and in respect of securing access to the site:</p>
<p>"I want authN method X in production but in preview I want authN method Y followed by authN method X"</p>
<p>Out of the box Windows Identity Foundation (WIF) allows federation with Identity Provider X but does not support multiple federated sign-in such as "Identity Provider Y followed by Identity Provider X".</p>
<p>In the article I alluded to the fact that code existed for the scenario but I did not include it in the post; for various reasons it was not code I could simply make available. However, I did set myself the task of rewriting the entire stack of code in a more generic way so that it could be picked up by developers who wished to protect their website using multiple federated sign-ins.</p>
<p>Roll forwards two years and purely due to a colleague asking a question that skirted around federation, I span up my development VM and, before I knew what I was doing, the code samples were finished!</p>
<p>The code samples have been uploaded <a href="https://code.msdn.microsoft.com/Access-to-an-ASPNET-3ebde116">here</a>. The rest of this article is a description of what is included and how it works.</p>
<p>Firstly though I have a confession to make. I envisioned that this solution would be possible using WIF 4.5 and the System.IdentityModel namespace but did not 100% confirm this to be the case. The scenario I knew that worked at the time was for WIF 4.0 and the Microsoft.IdentityModel namespace. i.e. &ndash; before WIF was baked into the .NET framework. So, the sample provided is for WIF 4.0 but I make a vow here and now to also get this working for WIF 4.5 in the very near future, if possible. Seeing as I have waited two years to get this far you can be sure that I will (eventually) research this.</p>
<h2>Methodology</h2>
<p>The approach is completely configuration driven by making sure the correct WIF modules are present in the web.config file for your site but preceded by a custom module I have called BouncerModule40 (Bouncer because the module acts like a nightclub doorman):</p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 1831px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 9px; padding-right: 9px; border: solid 0.5pt;">
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;<span style="color: #a31515;">system.webServer<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">modules<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">BouncerModule40<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Bouncer.WebApp40.BouncerModule40<span style="color: black;">"<span style="color: blue;">/&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">SessionAuthenticationModule<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Microsoft.IdentityModel.Web.SessionAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">WSFederationAuthenticationModule<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Microsoft.IdentityModel.Web.WSFederationAuthenticationModule, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">modules<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;/<span style="color: #a31515;">system.webServer<span style="color: blue;">&gt;</span></span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>The order of these modules is <em>critical</em> because we want the custom code to run <strong>before </strong>out of the box WIF gets its hands on the request.</p>
<p>Multiple federated sign ins are driven by including one or more named WIF Service elements, and a custom configuration section, as shown below:</p>
<h3>Custom config:</h3>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 448px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 9px; padding-right: 9px; border: solid 0.5pt;">
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;<span style="color: #a31515;">identityProvidersToCall<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">identityProviders<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">serviceName<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">IDP0<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">callSequenceNumber<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">0<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">serviceName<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">IDP1<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">callSequenceNumber<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">1<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">identityProviders<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;/<span style="color: #a31515;">identityProvidersToCall<span style="color: blue;">&gt;</span></span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<h3>WIF config:</h3>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 1831px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 9px; padding-right: 9px; border: solid 0.5pt;">
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;<span style="color: #a31515;">microsoft.identityModel<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">service<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">IDP0<span style="color: black;">"<span style="color: blue;">&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">value<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">certificateValidation<span style="color: blue;"> <span style="color: red;">certificateValidationMode<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">None<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">wsFederation<span style="color: blue;"> <span style="color: red;">passiveRedirectEnabled<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">issuer<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERENDPOINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">realm<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">requireHttps<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">cookieHandler<span style="color: blue;"> <span style="color: red;">requireSsl<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35<span style="color: black;">"<span style="color: blue;">&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">thumbprint<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDPPUBLICKEYCERTIFICATETHUMBPRINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERFRIENDLYNAME**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">service<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">service<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">IDP1<span style="color: black;">"<span style="color: blue;">&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">value<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">certificateValidation<span style="color: blue;"> <span style="color: red;">certificateValidationMode<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">None<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">wsFederation<span style="color: blue;"> <span style="color: red;">passiveRedirectEnabled<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">issuer<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERENDPOINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">realm<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">requireHttps<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">cookieHandler<span style="color: blue;"> <span style="color: red;">requireSsl<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35<span style="color: black;">"<span style="color: blue;">&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">thumbprint<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDPPUBLICKEYCERTIFICATETHUMBPRINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERFRIENDLYNAME**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">service<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">service<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">value<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">audienceUris<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">certificateValidation<span style="color: blue;"> <span style="color: red;">certificateValidationMode<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">None<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">wsFederation<span style="color: blue;"> <span style="color: red;">passiveRedirectEnabled<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">issuer<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERENDPOINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">realm<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**RELYINGPARTYURI**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">requireHttps<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">cookieHandler<span style="color: blue;"> <span style="color: red;">requireSsl<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">true<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">federatedAuthentication<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;"> <span style="color: red;">type<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">Microsoft.IdentityModel.Tokens.ConfigurationBasedIssuerNameRegistry, Microsoft.IdentityModel, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35<span style="color: black;">"<span style="color: blue;">&gt;</span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;<span style="color: #a31515;">add<span style="color: blue;"> <span style="color: red;">thumbprint<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDPPUBLICKEYCERTIFICATETHUMBPRINT**<span style="color: black;">"<span style="color: blue;"> <span style="color: red;">name<span style="color: blue;">=<span style="color: black;">"<span style="color: blue;">**IDENTITYPROVIDERFRIENDLYNAME**<span style="color: black;">"<span style="color: blue;"> /&gt;</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">trustedIssuers<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">issuerNameRegistry<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;"> &lt;/<span style="color: #a31515;">service<span style="color: blue;">&gt;</span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 8pt; background-color: white;">&lt;/<span style="color: #a31515;">microsoft.identityModel<span style="color: blue;">&gt;</span></span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p>(Apologies for the place markers, I didn't want to give away the details of my Azure AD tenant)</p>
<p>The bouncer module will deal with each Service element in the order indicated by the custom identityProvidersToCall element. In this case, IDP0 will be used for authentication, followed by IDP1. After the bespoke authentications have succeeded, control is handed back to WIF proper and the unnamed Service element (at the bottom of the snippet above) is processed. This final Service element would ordinarily be the intended production sign-in for the site and ultimately produce the session cookie used to authorise all future access to the website. The bespoke authentications, after having been negotiated, are necessarily thrown away.</p>
<h2>Conclusion</h2>
<p>The scenarios that warrant the existence of this code are fairly niche but I have actually been asked where the code is a few times over the past two years. Whilst to properly exercise what I have given you will require the particulars of your own domain, I hope this code can be your starter for 10.</p>
<p>Good luck and no, I haven't forgotten my promise to try and make this work for WIF 4.5.</p>
<p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/bradley+cotier/default.aspx">Bradley Cotier</a></p>]]></content:encoded>
    </item>
    <item>
      <title>LINQ, collections and null reference exceptions</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/linq-collections-and-null-reference-exceptions</link>
      <pubDate>Mon, 27 Oct 2014 09:28:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/10/27/linq-collections-and-null-reference-exceptions/</guid>
      <description><![CDATA[This short post describes an idiosyncrasy of LINQ that, for someone with several years of C#...]]></description>
      <content:encoded><![CDATA[<p>This short post describes an idiosyncrasy of <a href="http://msdn.microsoft.com/en-us/library/bb397926.aspx">LINQ</a> that, for someone with several years of C# experience I should probably have known about, but didn't.</p>
<p>During development of an app the test team reported that a <a href="http://msdn.microsoft.com/en-us/library/system.nullreferenceexception(v=vs.110).aspx">null reference exception</a> was intermittently occurring. For a seasoned developer like myself I didn't think it would be too hard to repro the issue and in fact null reference exception candidates can often be identified simply by eyeballing the code. I had a stack trace and so knew which method to look in.</p>
<p>From the method in question, I thought I saw the culprit and the story went like this.</p>
<p>Say you have a class of some type:</p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 623px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;">
<p><span style="color: blue; font-family: Consolas; font-size: 9pt; background-color: white;">class<span style="color: black;"> <span style="color: #2b91af;">Foo</span></span></span></p>
<p><span style="color: black; font-family: Consolas; font-size: 9pt; background-color: white;">{ </span></p>
<p><span style="color: black; font-family: Consolas; font-size: 9pt; background-color: white;"> <span style="color: blue;">public<span style="color: black;"> <span style="color: blue;">string<span style="color: black;"> FooString { <span style="color: blue;">get<span style="color: black;">; <span style="color: blue;">set<span style="color: black;">; } </span></span></span></span></span></span></span></span></span></p>
<p><span style="color: black; font-family: Consolas; font-size: 9pt; background-color: white;">}</span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><span style="color: black;">And you use an instance of the type in a LINQ query: </span></p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 623px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;">
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">Foo<span style="color: black;"> someFoo = <span style="color: blue;">new<span style="color: black;"> <span style="color: #2b91af;">Foo<span style="color: black;">(); </span></span></span></span></span></span></p>
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt; fooCollection = <span style="color: blue;">new<span style="color: black;"> <span style="color: #2b91af;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt;(); </span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 9pt; background-color: white;">var<span style="color: black;"> matchingFoo = fooCollection.FirstOrDefault(f =&gt; f.FooString == someFoo.FooString);</span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><span style="color: black;">All is well with the world. Now, what would happen when the following piece of code executes? </span></p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 623px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;">
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">Foo<span style="color: black;"> someFoo = <span style="color: blue;">null<span style="color: black;">; </span></span></span></span></p>
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt; fooCollection = <span style="color: blue;">new<span style="color: black;"> <span style="color: #2b91af;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt;(); </span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 9pt; background-color: white;">var<span style="color: black;"> matchingFoo = fooCollection.FirstOrDefault(f =&gt; f.FooString == someFoo.FooString);</span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><span style="color: black;">someFoo is null and so when the predicate is evaluated, a null reference exception occurs. Problem solved &hellip; right? </span></p>
<p><span style="color: black;">Wrong! This code does not cause an error. However, the following code does: </span></p>
<div>
<table style="border-collapse: collapse;" border="0"><colgroup><col style="width: 623px;" /></colgroup>
<tbody valign="top">
<tr>
<td style="padding-left: 7px; padding-right: 7px; border: solid 0.5pt;">
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">Foo<span style="color: black;"> someFoo = <span style="color: blue;">null<span style="color: black;">; </span></span></span></span></p>
<p><span style="color: #2b91af; font-family: Consolas; font-size: 9pt; background-color: white;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt; fooCollection = <span style="color: blue;">new<span style="color: black;"> <span style="color: #2b91af;">List<span style="color: black;">&lt;<span style="color: #2b91af;">Foo<span style="color: black;">&gt;(); </span></span></span></span></span></span></span></span></span></span></p>
<p><span style="color: black; font-family: Consolas; font-size: 9pt; background-color: white;">fooCollection.Add(<span style="color: blue;">new<span style="color: black;"> <span style="color: #2b91af;">Foo<span style="color: black;">()); </span></span></span></span></span></p>
<p><span style="color: blue; font-family: Consolas; font-size: 9pt; background-color: white;">var<span style="color: black;"> matchingFoo = fooCollection.FirstOrDefault(f =&gt; f.FooString == someFoo.FooString);</span></span></p>
</td>
</tr>
</tbody>
</table>
</div>
<p>&nbsp;</p>
<p><span style="color: black;">The only difference is that in the first instance the collection is empty, in the second example it is populated. </span></p>
<p><span style="color: black;">Retrospectively, the answer is obvious. Under the covers the predicate would be expanded into a <a href="http://msdn.microsoft.com/en-us/library/vstudio/ttw7t8t6(v=vs.110).aspx">foreach</a> loop which, for an empty collection, would never get executed. </span></p>
<h1>Conclusion</h1>
<p>This post is mostly for interest sake and the conclusions to be drawn are not revelatory. Always check for nulls and don't assume you know it all.</p>
<p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/bradley+cotier/default.aspx">Bradley Cotier</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Miracast in Enterprise Environments - FAQ</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/miracast-in-enterprise-environments-faq</link>
      <pubDate>Thu, 11 Sep 2014 04:50:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/09/11/miracast-in-enterprise-environments-faq/</guid>
      <description><![CDATA[Intro
This blog is intended to document our learning's about Miracast technology and explain things...]]></description>
      <content:encoded><![CDATA[<p><span style="font-size: large;">Intro</span></p>
<p>This blog is intended to document our learning's about Miracast technology and explain things to consider when implementing a solution using Miracast. It is primarily about Windows 8.1 tablets and Windows Phone 8.1 as the authors work for Microsoft in the Worldwide Modern Devices Centre of Excellence (CoE). We work on a program called First Wave which assists market leading customers in using and deploying the latest Windows technologies. For video case studies around our projects go to <a href="http://www.microsoft.com/en-us/windows/enterprise/customer-stories/default.aspx">http://www.microsoft.com/en-us/windows/enterprise/customer-stories/default.aspx</a> .</p>
<p>The authors, Lutz Seidemann (Infra) and Paul Tallett (App Dev), are Solution Architects with Microsoft Consulting Services &ndash; Worldwide Modern Device Center of Excellence.</p>
<p>We worked on many global projects but the relevant one is the Mandarin Oriental Hotel Group , which is detailed in our second blog.&nbsp;</p>
<p><span style="font-size: large;">FAQ</span></p>
<p><strong>Why do I want Miracast?</strong><br />Miracast technology allows you to wirelessly project your computer/tablet or phone screen onto an HDMI connected device such as a TV or projector. You can play movies for all the family to enjoy or simply enjoy a shared web browsing experience without the need for messy cables. It is similar in concept to Apple&rsquo;s AirPlay</p>
<p><strong>What is Miracast?</strong><br />Windows and Windows Phone 8.1 added support for Miracast projection from most devices and can either use a &ldquo;dongle&rdquo; that plugs into your TV or nowadays some TVs come with Miracast built in. Often the dongle is USB powered so can plug into a spare USB port on your TV. Most of the dongles are about the size of a pack of cards but some low cost USB-stick-sized devices are starting to emerge.<br /><a href="http://www.amazon.co.uk/Actiontec-SBWD100A01-ScreenBeam-Wireless-Receiver/dp/B00KSAYMH4">http://www.amazon.co.uk/Actiontec-SBWD100A01-ScreenBeam-Wireless-Receiver/dp/B00KSAYMH4</a> <br /><br />Technically it was designed as a &ldquo;wireless HDMI cable&rdquo; so you can think of it that way.</p>
<p><strong>What is the user experience like?</strong><br />Plug your dongle into the TV and select the correct AV port on the TV and you will see a &ldquo;Device ready for pairing&rdquo; type message on the TV. On Windows 8.1 select Devices/Project from the Charms Bar and click on &ldquo;Add a wireless display&rdquo;. The computer will scan for devices in range and allow you to select one and go through the pairing process which may involve typing a PIN that is displayed on the TV screen. This is all rather similar to pairing a Bluetooth mouse or headset (but doesn&rsquo;t actually involve Bluetooth).On the phone, go to Settings/&rdquo;Project My Screen&rdquo; and a similar scanning/pairing process will be initiated.</p>
<p>Once you have paired the device, it is persistent and you will not need to re-pair the device unless you pair the dongle with another device &ndash; you will simply be able to connect and display. You can pair with as many devices as you like and can unpair the device from Control Panel or Settings.</p>
<p>Note that once you log off or reboot your device, the mirrored connection is broken and cannot be re-established automatically. There are currently no public APIs to control Miracast projection.</p>
<p><strong>What is performance like?</strong><br />Performance varies with many factors &ndash; dongle manufacturer, computer CPU power, Wi-Fi traffic, Wi-Fi waveband etc (more details later) but you should be able to stream an HD movie from the Internet and project it to your TV with minimal stuttering. Note Miracast also transmits your sound channel as well as the picture.</p>
<p><strong>What components are used in Miracast?</strong><br />Miracast support is embedded into the display drivers, Wi-Fi drivers and device firmware (including dongle firmware) and it is quite sensitive to driver versions and revisions. The Miracast standard is constantly being tweaked and although backwards compatibility is promised, it is not always transparent. Each large Windows or phone update has required an update to the various components which may be on different delivery schedules. For example, getting a firmware update to the Miracast support in a TV is often a lengthy process and for this reason we recommend using a dongle rather than relying on the TV support. ActionTec have proved very responsive to requests and are tightly integrated into the Windows Operating System team (OSG) so they are the partner of choice for our team.</p>
<p>If you are experiencing problems, make sure you have all the latest drivers and hardware/dongle firmware installed.</p>
<p><strong>What technology does Miracast use?</strong><br />Miracast is an evolution of Intel&rsquo;s proprietary Wireless Display (WiDi) technology and uses the Wi-Fi Direct protocol and therefore communicates directly between device and dongle without going through a Wireless Access Point or router. However, the first stage of establishing a Miracast connection senses if the computer Wi-Fi adaptor is already using a Wi-Fi connection with a router and uses the assigned channel for the Miracast communication to prevent thrashing in the Wi-Fi adaptor.</p>
<p>We have not seen dongles that allow the Wi-Fi channel to be manually configured so if the computer is moved and switches channel for signal strength reasons, the Miracast session may become choppy or even disconnect as it tries to switch Wi-Fi channel. Since the bandwidth requirement for transmitting HD video is very high, having more than 3 or 4 dongles sharing the same channel will probably see saturation. Also remember that if you are streaming video wirelessly from the internet, that the stream will be transmitted twice over the Wi-Fi network, one to the computer and once to the dongle. Google&rsquo;s Chromecast differs in this respect as it can stream directly from the internet but only for certain applications.</p>
<p><strong>What methods are available for pairing a device?</strong></p>
<p>We have seen several methods of pairing the device:</p>
<ul>
<li><strong>Random Pin</strong>. Dongle displays a random PIN during the pairing process which must be manually typed into the computer to pair. This prevents pairing with a device that you cannot see, for example a TV in an adjacent hotel room.</li>
<li><strong>Automatic pairing</strong>. Introduced on Windows in 8.1 Update 1 as the default, a device can automatically pair when you select it. Disabling this feature is sometimes desirable (eg hotel) but has to be done in the dongle firmware if it supports it but not from Windows.</li>
<li><strong>Fixed secret PIN</strong>. Some dongles support manually setting a secret PIN in the dongle firmware. This prevents the device from being ad-hoc paired to other devices (eg a hotel guest using his phone) and affords greater control. When pairing you will need to know what PIN has been set or you will be unable to use the device.</li>
<li><strong>NFC or QR code</strong>. Some devices are starting to emerge that use more convenient methods to pair than having to type a PIN. For example Nokia&rsquo;s solution uses NFC <a href="http://www.wpcentral.com/hands-on-microsoft-screen-sharing-lumia-phones">http://www.wpcentral.com/hands-on-microsoft-screen-sharing-lumia-phones</a></li>
</ul>
<p><strong>How do I manage the dongle?</strong><br />Different vendors implement various methods of performing management tasks for the dongle such as upgrading the firmware or changing settings such as device name or timeouts. Some use a local USB port where you load the firmware then press a button on the device to flash it, other use mini web servers on the device (like a router) and present an HTML interface so that they can be managed remotely. Some flavors of the ActionTec firmware use a custom SSID that you connect to in order to manage the device which is a problem if you have a lot of devices as they pollute the experience when trying to connect a laptop to a Wi-Fi network for example, as all the dongle admin SSIDs are visible. You may be able to set the admin SSID to hidden.</p>
<p><strong>Do all Windows 8.1 and Windows Phone 8.1 devices support Miracast?</strong><br />No. This requires both hardware (Wi-Fi adaptor) and device firmware support.</p>
<p>We have tested the following list of devices successfully: Surface Pro 1, Surface Pro 2, Surface Pro 3, Dell Venue 8 Pro, HP ElitePad, Nokia 630, 1020, 1520. Note these may require a firmware upgrade to add this support depending on the age of the device.</p>
<p>The following devices do not support Miracast: original Surface RT.</p>
<p>Android 4.2 (JellyBean) or better (eg KitKat) is needed for Miracast support. Apple devices do not support Miracast as they use AirPlay which is a competing proprietary solution (implemented on Apple TV).</p>
<p><strong>Do all TVs and projectors support Miracast?</strong><br />You almost always require an HDMI input on the TV, so devices that do not have HDMI can be eliminated. Most Miracast solutions use 1080p for their screen resolution, but many HD TVs only support 1080i or 720p. 720p is not really sufficient for Windows 8 as it is below the minimum resolution for Modern Apps so you can&rsquo;t start a Modern app when running at that resolution. Some of the dongles (eg ActionTec) however, do support 1080i and the results can be very good. (P=Progressive, I=Interlaced, Progressive shows every line, Interlaced draws every other line then goes back and fills in the alternate lines). Picture quality is generally better on 1080p. Resolutions higher than 1080p (1920x1080) are not currently supported by Miracast so 4K for example is not supported.</p>
<p>We tested various dongles (Netgear, ActionTec, Belkin) and TVs with embedded Miracast support (Samsung, Philips, Sony) and arrived at the conclusion that the ActionTec dongle was the most flexible in terms of environment/features and gave the best performance. Also the engineering team were very responsive and turned around custom firmware versions in a few days. For this reason our team would recommend the ActionTec dongle.</p>
<p><strong>Can I add a button to the Windows 8.1 Start Screen to project the screen to aid discovery?</strong><br />There are no public APIs to control Miracast projection but attached is&nbsp;sample&nbsp;code that you can pin to the start screen that sends keystrokes to invoke the screen selection menu. The same menu is used for connection or disconnection so the app does not need any knowledge of whether the device is currently projecting or not.</p>
<p><strong>The projection stutters or drops. How can I improve performance?</strong><br />In a single device setting, make sure you have all the latest drivers and firmware releases including dongle firmware. If these still cause issues, you can experiment with older versions of the drivers as sometimes this helps</p>
<p><br />If you can set up a 5GHz Wi-Fi network rather than 2.4GHz (the default) and get your computers to use that by default, this will generally give better results. 5GHz has higher bandwidth but shorter range so your mileage may vary.</p>
<p>In a multi-device setting (e.g. hotel) network traffic may be an issue if multiple devices are using the same channel or if the network has a lot of traffic. Most Wi-Fi Access Points (AP) can be configured to prefer a certain channel, spacing these out across your environment in a matrix arrangement can considerably improve overall Wi-Fi performance. Using a signal strength meter to obtain hard data on signal strength is very important here. There are some signal strength apps available on smart phones if you don&rsquo;t have a specialized device. Again using 5GHz can be advantageous although 2.4GHz networks can still provide good results if properly configured. Remember that although the Miracast communication uses Wi-Fi Direct and does not go via your router, the channel it uses is determined by the Wi-Fi channel being used by the computer and your connection may not automatically upgrade and switch if a better channel is available.</p>
<p>Note you may need to update your Access Point firmware in order to set up a 5GHz network or control channel separation.</p>
<p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/lutz+seidemann/default.aspx">Lutz</a> and <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/paul+tallett/default.aspx">Paul</a></p>
<p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the <a href="http://www.microsoft.com/info/cpyright.mspx">Terms of Use</a>.</strong></p>
<p>&nbsp;</p>]]></content:encoded>
    </item>
    <item>
      <title>Miracast in Enterprise Environments</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/miracast-in-enterprise-environments</link>
      <pubDate>Thu, 11 Sep 2014 02:13:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/09/11/miracast-in-enterprise-environments/</guid>
      <description><![CDATA[Miracast in Enterprise Environments
This blog is intended to document our learning's about Miracast...]]></description>
      <content:encoded><![CDATA[<p><strong><span style="font-size: large;">Miracast in Enterprise Environments</span></strong></p>
<p><br />This blog is intended to document our learning's about Miracast technology and explain things to consider when implementing a solution using Miracast. It is primarily about Windows 8.1 tablets and Windows Phone 8.1 as the authors work for Microsoft in the Worldwide Modern Devices Centre of Excellence (CoE). We work on a program called First Wave which assists market leading customers in using and deploying the latest Windows technologies. For video case studies around our projects go to <a href="http://www.microsoft.com/en-us/windows/enterprise/customer-stories/default.aspx">http://www.microsoft.com/en-us/windows/enterprise/customer-stories/default.aspx</a><br /><br />The authors, Lutz Seidemann (Infra) and Paul Tallett (App Dev), worked on many of these projects but the relevant one is the Mandarin Oriental Hotel Group project which is detailed in the Customer Scenarios section. Both are Solution Architects with Microsoft Consulting Services &ndash; Worldwide Modern Device Center of Excellence.<br /><br /><span style="font-size: medium;"><strong>What is Miracast</strong></span></p>
<p>What is Miracast and how you can use it in your architectural concepts?</p>
<p>Let's have a first look to Wikipedia: <br />"Miracast is a peer-to-peer wireless screencasting standard formed via Wi-Fi Direct connections in a manner similar to Bluetooth. It enables wireless delivery of audio and video to or from desktops, tablets, mobile phones, and other devices. It allows users to, for example, echo display from a phone or tablet onto a TV, share a laptop screen with the conference room projector in real-time, and watch live programs from a home cable box on a tablet. Both the sending and receiving devices must support Miracast for the technology to work. However, to stream music and movies to a device, such as a TV, that does not support Miracast, adapters are available that plug into HDMI or USB ports. Miracast allows a portable device or computer to send, securely, up to 1080p HD video and 5.1 surround sound (AAC and AC3 are optional codecs, mandated codec is linear pulse-code modulation &mdash; 16 bits 48 kHz 2 channels).The protocol uses a direct Wi-Fi connection between the two devices without involvement of a wireless router and cannot be used to stream to a router access point. It was created by the Wi-Fi Alliance." (From &lt;<a href="http://en.wikipedia.org/wiki/Miracast">http://en.wikipedia.org/wiki/Miracast</a>&gt;)</p>
<p>Ok, here the same again in a nutshell: <br />Miracast is a protocol that will transmit audio and video between devices via Wi-Fi. It relies on the Wi-Fi network available (802.11n), using 2.4GHz and 5GHz bands. With this, you can enjoy multimedia content streaming from any Miracast enabled device such as your Windows 8.1 Tablet or Windows Phone to the Miracast device in our environment. It is not necessary that both devices are connected to the Internet. They only need to share the same local wireless network. The shared information is sent by the device via Wi-Fi through a Wi-Fi Direct connection to a receiver connected to the display device. The receiver then decodes the video signal and passes it to the TV display (or other display device). Miracast supports WPA2-PSK encryption, so all you share is safe. <br />Windows 8.1 or Android with version 4.2 and higher support Miracast natively. For Windows 7 you need to download the Intel WIDI drivers. If you familiar what Apple called Airplay, Miracast works similarly.<br />&nbsp;<br /><strong><span style="font-size: medium;">Miracast Devices</span></strong><br />Broadcasting photos, videos, music and other media from your mobile device or PC to your TV need not be a laborious process, fraught with wires and extra peripherals. Miracast, and Intel's compatible cousin technology WiDi, let you beam whatever is on your device's screen right to a television, and there's a good chance that the devices you already own have this technology built in.</p>
<p>Nowadays, all Windows 8.1 PCs with recent Intel CPUs and Wi-Fi cards already have the hardware necessary. On the phone side windows 8.1 phones and Android 4.2 Jelly Bean or later you can use to send a Miracast signal. If you have a Miracast-capable Phone or Tablet, all you need is a receiver to attach to your home theater. To help you choose, have a look on current Miracast receivers.</p>
<p><strong>Step 1.)</strong> Select your Miracast receiver<br />&nbsp;<img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/1854.image003.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/1854.image003.png" alt="" width="210" height="142" border="0" /><br />Rocketfish Miracast Video Receiver ($79.99):<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7713.image005.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7713.image005.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7713.image005.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7713.image005.png" alt="" width="235" height="174" border="0" /></a><br />Belkin Screencast 4.0.18.0 ($119.99):&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/6116.image007.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/6116.image007.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/6116.image007.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/6116.image007.png" alt="" width="218" height="144" border="0" /></a><br />Netgear Push2TV PTV3000&nbsp; ($59.99)<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/5037.image009.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/5037.image009.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/5037.image009.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/5037.image009.png" alt="" width="160" height="143" border="0" /></a><br />D-Link DHD-131 ($99.99)</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/1348.image011.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/1348.image011.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/1348.image011.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/1348.image011.png" alt="" width="171" height="140" border="0" /></a><br />Actiontec Screen-Beam Pro ($69.99)</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7230.image013.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7230.image013.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7230.image013.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7230.image013.png" alt="" width="200" height="130" border="0" /></a><br />Lumia HD-10 ($79.99)</p>
<p>You need make sure the Miracast device is compatible with your TV. Most Miracast solutions use 1080p for their screen resolution, but many older TVs only support 1080i or even only 720p. The only device we found that can support 1080i &amp; 1080p is the Actiontec Screen-Beam Pro.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7701.image015.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7701.image015.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7701.image015.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7701.image015.png" alt="" width="227" height="146" border="0" /></a></p>
<p>The Wi-Fi Alliance website maintains a comprehensive list of compatible devices, although that list does not account for Miracast-compatible technologies like Samsung's AllCast Share. More information, including a list of Wi-Fi Certified Miracast products, the Wi-Fi Alliance Display technical specification, white paper, and more is available at <a href="http://www.wi-fi.org/miracast">www.wi-fi.org/miracast</a>.</p>
<p><strong>Step 2.)</strong> Connect your Miracast receiver to your TV<br />All Miracast receivers plug into a TV's HDMI port and are ready to receive as soon as they turn on.</p>
<p><strong>Step 3.)</strong> Connect your Windows 8.1 PC or Tablet&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/3073.image017.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/3073.image017.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/3073.image017.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/3073.image017.png" alt="" width="202" height="286" border="0" /></a><br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/0257.image019.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/0257.image019.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/0257.image019.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/0257.image019.png" alt="" width="203" height="239" border="0" /></a><br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/2100.image021.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/2100.image021.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/2100.image021.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/2100.image021.png" alt="" width="231" height="108" border="0" /></a></p>
<p>After you added your Miracast connection , from now you can access via the usual project option.<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/4718.image023.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/4718.image023.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/4718.image023.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/4718.image023.png" alt="" width="208" height="198" border="0" /></a>&nbsp;<br />For detailed instructions have a look <a href="http://windows.microsoft.com/en-us/windows-8/project-wireless-screen-miracast">here </a>.</p>
<p><strong>Step 3.a)</strong> Connect your Windows 8.1 Phone&nbsp;<br />&nbsp;<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/1016.image025.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/1016.image025.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/1016.image025.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/1016.image025.png" alt="" width="276" height="441" border="0" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/5850.image027.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/5850.image027.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/5850.image027.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/5850.image027.png" alt="" width="277" height="334" border="0" /></a><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/0447.image029.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/0447.image029.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/0447.image029.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/0447.image029.png" alt="" width="270" height="335" border="0" /></a></p>
<p>&nbsp;</p>
<p>After you tap your phone is displayed to the TV<br /><br /><strong>Step 3.b)</strong> Connect your Android Phone</p>
<p>Note: instructions differ depending on whether you are streaming from an different Android version. This is Android 4.4 (KitKat)</p>
<p>Go to Settings/Connections and tap on Screen Mirroring<br />&nbsp;<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7345.image033.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7345.image033.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/7345.image033.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/7345.image033.png" alt="" width="257" height="441" border="0" /></a></p>
<p>You will then see this screen and you can tap your Miracast dongle:<br />&nbsp;<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/6138.image035.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/6138.image035.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/6138.image035.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/6138.image035.png" alt="" width="258" height="492" border="0" /></a></p>
<p>The device will go through the pairing process:<br /><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/8080.image037.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/8080.image037.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/8080.image037.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/8080.image037.png" alt="" width="260" height="487" border="0" /></a>&nbsp;<br />And your screen is now mirrored and you can tap to disconnect:<br />&nbsp;<a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/3010.image039.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/3010.image039.png"><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/3010.image039.png" original-url="http://blogs.msdn.com/resized-image.ashx/__size/550x0/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14/3010.image039.png" alt="" width="265" height="510" border="0" /></a><br />&nbsp;<br /><strong><span style="font-size: medium;">Customer Scenario</span></strong></p>
<p>One year ago Mandarin Oriental partnered up with Microsoft in early adopter program called Windows Firstwave. Mandarin Oriental&rsquo;s intention is to make its wealth of online marketing content, hotel information and guest services more easily accessible to its digitally savvy guests. Leveraging the Microsoft platform, Mandarin Oriental is able to integrate a combination of services formerly offered via the television, telephone or guest directory with content available on the company&rsquo;s website to deliver a more intuitive in-room experience for guests via custom touch apps running on Microsoft Surface Pro tablets. The Mandarin Oriental Group has piloted Microsoft Surface Pro tablets in four of their award-winning properties in London, Washington DC, Las Vegas and Tokyo.</p>
<p>Microsoft Consulting Services worked together with the hospitality solutions partner iRiS Software Systems, InterKnowlogy to develop a suite of custom Windows 8.1 touch apps, available in nine different languages, that manage services for in-room dining, concierge and housekeeping requests, a guest compendium which provides information about the hotel&rsquo;s facilities and access to guest feedback and guest preferences.</p>
<p>Here a quick overview of the solution architecture before we go deep on our Miracast implementation experiences during the pilot:</p>
<p>During the Architecture design session we proposed to use Windows Embedded 8.1 Industry on Microsoft Surface Pro to Mandarin Oriental. This version of Windows 8.1 is functionally identical to the consumer/pro versions of Windows 8.1 with the exception that Embedded 8.1 industry adds capabilities to lock down the device - in this specific case a Write Filter is used to write all changes that happen to the OS after it is booted into a cache which is then overlaid on the file system. In normal operation this cache is transparent to the user and Industry Embedded 8.1 operates as any Windows 8.1 PC would. However when the Surface Pro is rebooted the cache is deleted restoring the Surface Pro device to the install state. This is how user state (files, downloaded apps, browsing history, customization, etc.) is removed through a reboot initiated at checkout. It's a simple and effective process and it's similar to the way that 3rd Party products (e.g. Deep Freeze) works except in this case, the capability is built into the OS making Surface Pro with Windows Industry 8.1 ideal for this type of commercial application. The user can install any app, download email, work on documents, change any configuration they want, including log into a Microsoft Account (MSA) with the surety that at checkout, or when the Surface device is rebooted, all user-specific data is removed.</p>
<p>Additionally, all OS updates are applied after checkout by automatically switching the device to Servicing Mode where the write filter is disabled and all the patches applied keeping the install image secure and up to date. For real-time updates required by application such as Defender or Microsoft Forefront you can add folder level write filter exclusions to prevent that data being wiped off at reboot. An important benefit of this approach is that specific hotel apps can be sourced from multiple developers, and these can be complemented by any app that can be downloaded from the Windows Store (the very functional Bing apps for example).</p>
<p>This contrasts with the alternative Android/iOS mechanisms in use for tablets deployed for this type of application in hotels. For these OS's which do not have such evolved management mechanisms, the typical approach is to build one large app that must contain all required functionality. The tablet is then locked in kiosk mode running this app only. Writing one big monolithic app is clearly a less efficient software development approach, and it removes from the user experience nearly all of the familiar tablet functionality associated with the OS - i.e. something as simple as a web browser - if such functionality is desirable to include in the user experience, must be written/included in the hotel app development process. In Windows 8.1 Industry Embedded such functionality, and much more, is included out of the box leaving the developers to spend their time and money developing line-of-business hotel-specific functionality which means they can be potentially much more productive.&nbsp;&nbsp; (Read the Mandarin Oriental Hotel Group <a href="http://www.microsoft.com/en-us/news/press/2014/jul14/07-15mandarinoriental.aspx">Press Release</a> , <a href="http://blogs.windows.com/business/2014/07/15/wpc-2014-partnering-to-win-in-the-mobile-era/">Blog</a> or watch the <a href="http://content2.catalog.video.msn.com/e2/ds/c8861ffd-2641-4294-a6ff-ea8baedc50bb.mp4">Video</a> )</p>
<p><strong>OK, let's circle back to Miracast, what this blog is all about :</strong><br />Part of the Mandarin Solution is Miracast to provide all guests the possibility to stream there preferred videos, watch Hulu or Netflix, internet TV channels or any other content direct on the big in-room TV. Imagine you go into a hotel room and can watch your preferred movie without messing around with a cable connection or different kinds of adapters. You just connect to Netflix and watch, I would call this very slick.</p>
<p>What you need consider to build such a solution?<br />Remember that although the Miracast communication uses Wi-Fi Direct and does not go via your router, the channel it uses is determined by the Wi-Fi channel being used by the computer and your connection may not automatically upgrade and switch if a better channel is available.</p>
<p>In a multi-device setting network traffic may be an issue if multiple devices are using the same channel or if the network has a lot of traffic. That&rsquo;s important for environments such as Hotels, where you have many Miracast devices (Dongle and PC/Phone) very close to each other.</p>
<p><strong>Understand your Wi-Fi Network:</strong><br />1.&nbsp;Most Wi-Fi Access Points (AP) can be configured to prefer a certain channel, spacing these out across your environment in a matrix arrangement can considerably improve overall Wi-Fi performance. Using a signal strength meter to obtain hard data on signal strength is very important here. There are some signal strength apps available on smart phones if you don&rsquo;t have a specialized device. <br />2.&nbsp;In general the 5GHz bandwidth is less noisy than 2.4GHz ; you can find baby monitors, microwave or Bluetooth devices sending on 2.4GHz. More information <a href="http://en.wikipedia.org/wiki/Electromagnetic_interference_at_2.4_GHz">here</a>.<br />3.&nbsp;If you can set up a 5GHz Wi-Fi network rather than 2.4GHz (the default) and get your computers to use that by default, this will generally give better results. 5GHz has higher bandwidth but shorter range so your mileage may vary. Configure your Router for "Optimize for compatibility" mode, which allow to configure a separated 5GHz channel per room (36,40,44,48,149,153,157,161).</p>
<p><strong>Drivers and Firmware</strong><br />4.&nbsp;Make sure you have all the latest Wi-Fi drivers and device firmware releases <br />5.&nbsp;Update your Miracast dongle firmware.<br />6.&nbsp;Update your Wi-Fi Router firmware, especially if you plan to go for 5Ghz infrastructure.<br />7.&nbsp;Update your TVs when using the build-in Miracast function<br />&nbsp;<br />&nbsp;<br /><strong>Code samples</strong> <br />For the Mandarin Oriental project we wrote a Modern app that sent keystrokes to invoke the charms bar and bring up the projection screen which we pinned to the Start Screen to make it very easy for guests to discover this functionality. Since Modern apps are not allowed to send keystrokes to the system, we used a technique called Brokered Components which allows desktop code to be called from a side-loaded Modern app. Sending the keystrokes is fairly trivial, here's the code we used in the Brokered Component:</p>
<p>private async Task&lt;int&gt; StartProjectionTask(int n) <br />{ <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; await Task.Delay(1); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputSimulator.SimulateModifiedKeyStroke(VirtualKeyCode.LWIN, VirtualKeyCode.VK_K); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.Sleep(1000);&nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;InputSimulator.SimulateKeyPress(VirtualKeyCode.DOWN); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputSimulator.SimulateKeyPress(VirtualKeyCode.DOWN); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Thread.Sleep(1000); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; InputSimulator.SimulateKeyPress(VirtualKeyCode.SPACE); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Thread.Sleep(3000); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //InputSimulator.SimulateKeyPress(VirtualKeyCode.UP); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //InputSimulator.SimulateKeyPress(VirtualKeyCode.UP); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //InputSimulator.SimulateKeyPress(VirtualKeyCode.UP); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //InputSimulator.SimulateKeyPress(VirtualKeyCode.SPACE); <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //Thread.Sleep(1000);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0; <br />}</p>
<p>Brokered Components in Windows 8.1 apps is documented in this article: <a href="http://msdn.microsoft.com/en-us/library/windows/apps/dn630195.aspx">http://msdn.microsoft.com/en-us/library/windows/apps/dn630195.aspx</a><br />And a step-by-step guide is here: <a href="http://devhawk.net/2014/04/25/brokered-winrt-components-step-one/">http://devhawk.net/2014/04/25/brokered-winrt-components-step-one/</a></p>
<p>&nbsp;<br /><span style="font-size: medium;"><strong>Summary</strong></span> <br />As a recap, Miracast is a very exciting technology and if you spend a little time on the key points it works very well. After testing a few dongles, we selected <a href="http://www.actiontec.com/303.html">ActionTec</a> because of the wider selection of TV resolution (1080i and 1080p) and configuration options we got in the firmware. Working with the Actiontec engineering team was a pleasure.</p>
<p>Your environment may differ, so we don&rsquo;t want to give a generic recommendation. Those are the critical components :</p>
<ul>
<li>Device Drivers</li>
<li>Dongle and Router Firmware</li>
<li>Wifi Network configuration&nbsp;</li>
<li>Miracast Dongle</li>
</ul>
<p>Finally, give us your feedback; share your implementation experiences; ask question and we will try to help.</p>
<p>Happy implementing! <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/lutz+seidemann/default.aspx">Lutz</a> and <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/paul+tallett/default.aspx">Paul</a></p>
<p><strong>Disclaimer: The information on this site is provided "AS IS" with no warranties, confers no rights, and is not supported by the authors or Microsoft Corporation. Use of included script samples are subject to the terms specified in the Terms of Use.</strong></p>]]></content:encoded>
    </item>
    <item>
      <title>Adding Trace to Azure Web Sites and Web Jobs</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/adding-trace-to-azure-web-sites-and-web-jobs</link>
      <pubDate>Thu, 04 Sep 2014 05:52:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/09/04/adding-trace-to-azure-web-sites-and-web-jobs/</guid>
      <description><![CDATA[Using standard .NET trace in Azure Web Sites and Web Jobs is an extremely simple affair, with trace...]]></description>
      <content:encoded><![CDATA[<p>Using standard .NET trace in Azure Web Sites and Web Jobs is an extremely simple affair, with trace output being directed to either table, blob or file storage without the need for any configuration file or code changes. This is great and a very welcome simplification compared to what you had with web and worker roles. However, if you prefer to use the enhanced tracing features offered by the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> class, then a little extra work is necessary. In this post we'll look at how to achieve this.</p>
<h2>Enabling Trace in Azure Web Sites and Web Jobs</h2>
<p>Let's quickly recap how to create trace statements and enable output in your web site or web job.</p>
<p>In your application you add relevant trace statements at strategic points, using an appropriate severity. This is achieved using the static methods on the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.trace(v=vs.110).aspx">Trace</a> class as follows:</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">System.Diagnostics.Trace.TraceError(<span style="color: #006080;">"TraceError WebSite"</span>);<br />System.Diagnostics.Trace.TraceInformation(<span style="color: #006080;">"TraceInformation WebSite"</span>);<br />System.Diagnostics.Trace.TraceWarning(<span style="color: #006080;">"TraceWarning WebSite"</span>);</pre>
</div>
<p>Once your application is deployed to Azure, you can enable output from the portal by going to the configure tab for the web site. The settings will apply to all web jobs running under that web site:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/2742.091614_0938_AddingTrace1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/2742.091614_5F00_0938_5F00_AddingTrace1.png" alt="" /></p>
<p>With the above settings, anything of verbose severity upwards will be logged to the file system and to Azure storage (table and blob). Clicking on the "manage &hellip;" buttons allow you to configure which table or blob container the output is written to. You really can't get simpler than that!</p>
<p>(Note: At the time of writing the new Azure portal currently allows you to only manage file system application logging. Managing application logging settings for table and blob is currently on the backlog and will be available in the near future. Alternatively you can use the <a href="https://github.com/projectkudu/kudu/wiki/REST-API">REST API</a> to apply these settings).</p>
<p>Here's what the trace output looks like in table storage:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/1106.091614_0938_AddingTrace2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/1106.091614_5F00_0938_5F00_AddingTrace2.png" alt="" /></p>
<p>Using the static <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.trace(v=vs.110).aspx">Trace</a> methods to generate such trace is fine for some applications but it has its limitations. For example, as shown in the above example you cannot specify an event id. Using these methods also prevent having finer grain control over what is output. For this reason, the <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> class was introduced to provide enhanced tracing features that can be used in place of the static <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.trace(v=vs.110).aspx">Trace</a> methods.</p>
<h2>Using TraceSource in Web Sites and Web Jobs</h2>
<p>When instrumenting an application it is sometimes desirable to provide tracing at different layers in the application architecture or for different components. For example, you may wish to have tracing specific to messaging, database access or business logic. Using <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> you can assign different <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> instances to those aspects of the application, and through configuration, control the behaviour of each <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> instance. I won't go into further details here but you can refer to the <a href="http://msdn.microsoft.com/en-us/library/zs6s4h68(v=vs.110).aspx">MSDN documentation</a> for further reading.</p>
<p>In this example, I've chosen to add three categories of events to my web site for which I will add three different <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> instances:</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> TraceSource Operational = <span style="color: #0000ff;">new</span> TraceSource(<span style="color: #006080;">"Operational"</span>);<br /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> TraceSource Messaging = <span style="color: #0000ff;">new</span> TraceSource(<span style="color: #006080;">"Messaging"</span>);<br /><span style="color: #0000ff;">public</span> <span style="color: #0000ff;">static</span> <span style="color: #0000ff;">readonly</span> TraceSource Diagnostics = <span style="color: #0000ff;">new</span> TraceSource(<span style="color: #006080;">"Diagnostics"</span>);</pre>
</div>
<p>Now I can generate events for each of the instances as required:</p>
<div id="codeSnippetWrapper">
<pre id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;">Operational.TraceEvent(TraceEventType.Warning, 101, <span style="color: #006080;">"TraceEvent WebSite Operational"</span>);<br />Messaging.TraceEvent(TraceEventType.Information, 102, <span style="color: #006080;">"TraceEvent WebSite Messaging"</span>);<br />Diagnostics.TraceEvent(TraceEventType.Verbose, 103, <span style="color: #006080;">"TraceEvent WebSite Diagnostics"</span>);</pre>
</div>
<p>One of the benefits of using a <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> is that you can assign an id to each event, to uniquely identify it in the output - crucial from an operations management perspective if you need to identify that a specific event has occurred.</p>
<p>In order to get <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> to work with Web Sites and Web Jobs, you need to be aware of three listener types that can be found in the Microsoft.WindowsAzure.WebSites.Diagnostics DLL. Currently these types are undocumented since the design goal has been to minimise configuration and typically you should not need to know about their existence. However, if you want to go off-piste and use <a href="http://msdn.microsoft.com/en-us/library/system.diagnostics.tracesource(v=vs.110).aspx">TraceSource</a> then you'll need to familiarize yourself with them because in your configuration you will have to reference the listener type in order to write events to the appropriate output:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/3348.091614_0938_AddingTrace3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/3348.091614_5F00_0938_5F00_AddingTrace3.png" alt="" /></p>
<p>In the Web.Config of your Web Site (or the App.Config of your Web Job), add the following configuration:</p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 97.5%; direction: ltr; text-align: left; margin: 20px 0px 10px; line-height: 12pt; max-height: 200px; background-color: #f4f4f4; border: silver 1px solid; padding: 4px;">
<pre id="codeSnippet" style="overflow: visible; font-size: 8pt; font-family: 'Courier New', courier, monospace; width: 100%; color: black; direction: ltr; text-align: left; margin: 0em; line-height: 12pt; background-color: #f4f4f4; border-style: none; padding: 0px;"><span style="color: #0000ff;">&lt;</span><span style="color: #800000;">system.diagnostics</span><span style="color: #0000ff;">&gt;</span><br /><br />    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">sharedListeners</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureTableTraceListener"</span> <span style="color: #ff0000;">type</span><span style="color: #0000ff;">="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureTableTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span> <span style="color: #0000ff;">/&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureBlobTraceListener"</span> <span style="color: #ff0000;">type</span><span style="color: #0000ff;">="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureBlobTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span> <span style="color: #0000ff;">/&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureDriveTraceListener"</span> <span style="color: #ff0000;">type</span><span style="color: #0000ff;">="Microsoft.WindowsAzure.WebSites.Diagnostics.AzureDriveTraceListener, Microsoft.WindowsAzure.WebSites.Diagnostics, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"</span> <span style="color: #0000ff;">/&gt;</span><br />    <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">sharedListeners</span><span style="color: #0000ff;">&gt;</span><br /><br />    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">sources</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">source</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Diagnostics"</span> <span style="color: #ff0000;">switchName</span><span style="color: #0000ff;">="DiagnosticsSourceSwitch"</span> <span style="color: #ff0000;">switchType</span><span style="color: #0000ff;">="System.Diagnostics.SourceSwitch"</span><span style="color: #0000ff;">&gt;</span><br />        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />          <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureDriveTraceListener"</span><span style="color: #0000ff;">/&gt;</span><br />        <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">source</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">source</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Messaging"</span> <span style="color: #ff0000;">switchName</span><span style="color: #0000ff;">="MessagingSourceSwitch"</span> <span style="color: #ff0000;">switchType</span><span style="color: #0000ff;">="System.Diagnostics.SourceSwitch"</span><span style="color: #0000ff;">&gt;</span><br />        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />          <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureTableTraceListener"</span><span style="color: #0000ff;">/&gt;</span><br />          <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureBlobTraceListener"</span><span style="color: #0000ff;">/&gt;</span><br />        <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">source</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">source</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="Operational"</span> <span style="color: #ff0000;">switchName</span><span style="color: #0000ff;">="OperationalSourceSwitch"</span> <span style="color: #ff0000;">switchType</span><span style="color: #0000ff;">="System.Diagnostics.SourceSwitch"</span><span style="color: #0000ff;">&gt;</span><br />        <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />          <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureTableTraceListener"</span><span style="color: #0000ff;">/&gt;</span><br />          <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="AzureBlobTraceListener"</span><span style="color: #0000ff;">/&gt;</span><br />        <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">listeners</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">source</span><span style="color: #0000ff;">&gt;</span><br />    <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">sources</span><span style="color: #0000ff;">&gt;</span><br /><br />    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">switches</span><span style="color: #0000ff;">&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="DiagnosticsSourceSwitch"</span> <span style="color: #ff0000;">value</span><span style="color: #0000ff;">="All"</span> <span style="color: #0000ff;">/&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="MessagingSourceSwitch"</span> <span style="color: #ff0000;">value</span><span style="color: #0000ff;">="All"</span> <span style="color: #0000ff;">/&gt;</span><br />      <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">add</span> <span style="color: #ff0000;">name</span><span style="color: #0000ff;">="OperationalSourceSwitch"</span> <span style="color: #ff0000;">value</span><span style="color: #0000ff;">="All"</span> <span style="color: #0000ff;">/&gt;</span><br />    <span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">switches</span><span style="color: #0000ff;">&gt;</span><br /><br />    <span style="color: #0000ff;">&lt;</span><span style="color: #800000;">trace</span> <span style="color: #ff0000;">autoflush</span><span style="color: #0000ff;">="true"</span> <span style="color: #ff0000;">indentsize</span><span style="color: #0000ff;">="4"</span> <span style="color: #0000ff;">/&gt;</span><br /><br /><span style="color: #0000ff;">&lt;/</span><span style="color: #800000;">system.diagnostics</span><span style="color: #0000ff;">&gt;</span></pre>
</div>
<div id="codeSnippetWrapper">Here we have defined three trace listeners, one for each of the Azure trace listener types. We've then defined three trace sources and assigned a listener to each of them. For the Diagnostics trace source, we will log to the file system and for Messaging and Operational trace sources we will write to table and blob storage. Here's what the output looks like:</div>
<h3><span style="background-color: white;">AzureTableTraceListener</span> output</h3>
<h3><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/6320.091614_0938_AddingTrace4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/6320.091614_5F00_0938_5F00_AddingTrace4.png" alt="" /></h3>
<h3><span style="background-color: white;">AzureBlobTraceListener</span> output (csv file)</h3>
<h3><span style="font-size: 10pt; font-family: courier new;">date,level,applicationName,instanceId,eventTickCount,eventId,pid,tid,message,activityId </span></h3>
<h3><span style="font-size: 10pt; font-family: courier new;">2014-09-04T11:09:13,Warning,logging,09482d,635454257537318640,101,12792,52,TraceEvent WebSite Operational, </span></h3>
<h3><span style="font-size: 10pt; font-family: courier new;">2014-09-04T11:09:14,Information,logging,09482d,635454257543880608,102,12792,52,TraceEvent WebSite Messaging,</span></h3>
<h3><span style="background-color: white;">AzureDriveTraceListener</span> output</h3>
<p><span style="font-size: 10pt; font-family: courier new;">2014-09-04T11:09:14 PID[12792] Verbose TraceEvent WebSite Diagnostics </span></p>
<h2>Using the Azure Web Site Logs Browser Site Extension</h2>
<p><a href="http://azure.microsoft.com/blog/2014/06/20/azure-web-sites-extensions/">Site extensions</a> are a great way of easily extending the functionality of your site through freely downloadable packages available from the <a href="http://www.siteextensions.net/packages">site extensions gallery</a>. One such site extension is the <a href="http://www.siteextensions.net/packages/websitelogs">Azure Web Site Logs Browser</a> which allows you to view your system and application logs (file, table and blob) through your web browser. Here's what the table storage content looks like:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/0576.091614_0938_AddingTrace5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/0576.091614_5F00_0938_5F00_AddingTrace5.png" alt="" /></p>
<p>So there you have it. Tracing in Web Site and Web Job applications using the standard .NET trace libraries is no different to any other .NET application. The key thing you need to know is what listener types you have available to you.</p>
<p>Happy tracing.</p>
<p><em>Written by Christopher Owczarek </em></p>
<p><em>Thanks to David Ebbo, Robert Jarratt and Amit Apple for their help in producing this post</em>.</p>]]></content:encoded>
    </item>
    <item>
      <title>Video Streaming with a custom IRandomAccessStream on Windows and Windows Phone (Universal App)</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/video-streaming-with-a-custom-irandomaccessstream-on-windows-and-windows-phone-universal-app</link>
      <pubDate>Sat, 12 Jul 2014 08:09:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/07/12/video-streaming-with-a-custom-irandomaccessstream-on-windows-and-windows-phone-universal-app/</guid>
      <description><![CDATA[&nbsp;
Overview
&nbsp;
We encountered a challenge on our project where we wanted to play videos...]]></description>
      <content:encoded><![CDATA[<p class="PadderBetweenControlandBody">&nbsp;</p>
<h2>Overview</h2>
<p>&nbsp;</p>
<p>We encountered a challenge on our project where we wanted to play videos in MediaElement but the MP4 file was stored in Sharepoint which required user credentials for authentication. If you pass a URL to the MediaElement on Windows Phone 8.1 then it just tried to access the file without passing any authentication information and there is no easy way to intercept this. We escalated this to the Product Group and got the response that this was by design.</p>
<h2>Solution</h2>
<p>We came up with the idea of writing a custom IRandomAccessStream and setting it on top of WebClient so we could manipulate the http requests going out, and we wanted to use range headers so we could request just a sequence of bytes from the server and would not need to download the whole MP4 file in order to stream it. Although simple in concept, this proved quite challenging and took many complete rewrites of our solution and a team effort where we were all contributing ideas and code, but we finally got it working, so I&rsquo;m posting it here.</p>
<p>There were&nbsp;three really tough problems &ndash;</p>
<ol>
<li>Get the IRandomAccessStream implemented properly so that MediaElement would stream and play it</li>
<li>Get the http RangeHeaders working so that we didn&rsquo;t need to download the whole file before it started<br />playing</li>
<li>Figuring out the mix of IAsyncOperationWithProgress and the async/Task feature so we could do async<br />operations in the middle of data requests</li>
</ol>
<p>We actually got each of the three pieces working separately before combining them into the working solution. The web proved very little help as there seemed to be a lot of people struggling with this but nobody seemed to get it working so hence this blog post. We also saw people trying custom MediaStreamSource implementations but that looked much more complex than the custom IRandomAccessStream if we could get it to work.</p>
<p>The solution posted here uses Universal apps and has a Phone project and a Windows 8.1 project so works on both platforms. Most of the files in the solution are pretty much just the standard template files with the exception of StreamingRandomAccessStream.cs and the following lines in MainPage.xaml.cs:</p>
<p>protected async override void OnNavigatedTo(NavigationEventArgs e)<br />{<br />&nbsp;&nbsp;&nbsp; var uri = new Uri("<a href="http://archive.org/download/RescuefromGilligansIsland/RescuefromGilligansIsland_512kb.mp4">http://archive.org/download/RescuefromGilligansIsland/RescuefromGilligansIsland_512kb.mp4</a>");<br />&nbsp;&nbsp;&nbsp; var headers = await StreamingRandomAccessStream.GetHeaders(uri);<br />&nbsp;&nbsp;&nbsp; ulong length = (ulong)headers.ContentLength;<br />&nbsp;&nbsp;&nbsp; string mimeType = headers.ContentType.MediaType;<br />&nbsp;&nbsp;&nbsp; var stream = new StreamingRandomAccessStream(null, uri, length);<br />&nbsp;&nbsp;&nbsp; mediaElement.SetSource(stream, mimeType);<br />}</p>
<p>Here you see us fetching the headers from the MP4 file and creating a new instance of StreamingRandomAccessStream which is where the magic happens. Note that the sample Gilligan&rsquo;s Island video does not actually need&nbsp;authentication but it was useful to test with as it is quite large. You&rsquo;ll need to replace the dummy usernames and passwords in the sample to use the authentication piece.</p>
<p>The StreamingRandomAccessStream has some static methods for managing the http traffic but where it all happens is really this method:</p>
<p>public IAsyncOperationWithProgress&lt;IBuffer, uint&gt; ReadAsync(IBuffer buffer, uint count, InputStreamOptions options)<br />{<br />&nbsp;&nbsp;&nbsp; return AsyncInfo.Run&lt;IBuffer, uint&gt;(async (cancellationToken, progress) =&gt;<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; progress.Report(0);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (_stream == null)<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var netStream = await GetStreamWithRange(_requestedUri, _requestedPosition, _requestedPosition + count);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _stream = netStream.AsInputStream();<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return await _stream.ReadAsync(buffer, count, options).AsTask(cancellationToken, progress);<br />&nbsp;&nbsp;&nbsp; });<br />}</p>
<p>This method is called through the IRandomAccessStream interface by the MediaElement to request the bytes of the video. The really tough bit that took a lot of wrestling with was getting the delegate signatures right and figuring out how to do an await in the middle of an IAsyncOperation.</p>
<p>Note when using range headers on Windows Phone there's a slight difference to Windows 8 in that the end position cannot be null on phone otherwise it throws an error, despite being a nullable type. This works fine on Windows 8.</p>
<p>Anyhow, hoping this blog post helps you and thanks to the team &ndash; Iestyn Jones, Simon Middlemiss and Paul Tallett.</p>
<p>Enjoy!</p>
<p>&nbsp;</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Components.PostAttachments/00/10/54/18/86/VideoTest.zip" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-components-postattachments/00-10-54-18-86/VideoTest.zip">VideoTest.zip</a></p>]]></content:encoded>
    </item>
    <item>
      <title>Using Application Insights to track Unhandled Exceptions in Windows Phone and Windows Store Apps</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/using-application-insights-to-track-unhandled-exceptions-in-windows-phone-and-windows-store-apps</link>
      <pubDate>Fri, 14 Mar 2014 04:33:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/03/14/using-application-insights-to-track-unhandled-exceptions-in-windows-phone-and-windows-store-apps/</guid>
      <description><![CDATA[Application Insights is a preview service offered as part of Visual Studio Online.&#160; If you...]]></description>
      <content:encoded><![CDATA[<p>Application Insights is a preview service offered as part of Visual Studio Online.&#160; If you don’t have access to the preview yet then keep an eye on <a href="http://blogs.msdn.com/b/bharry/">Brian Harry’s blog</a> for updates.</p>  <p>If you are lucky enough to have access and you are building a Windows Phone or Windows 8 application, then you can use this quick guide to allow you to track crashes in your apps.</p>  <p>Automatic exception logging in apps isn’t (yet?) a feature of Application Insights, but its perfectly possibly to use the in-build event logging functionality to do this.&#160; To make this happen you need to have first setup Application Insights for your app.&#160; I’m going to assume you’ve done this already as you’ve got this far.&#160; If you haven’t then check out these articles on MSDN on how to do so for <a href="http://msdn.microsoft.com/en-us/library/dn481093.aspx">Windows Phone</a> and <a href="http://msdn.microsoft.com/en-us/library/dn509554.aspx">Windows Store Apps</a> and then come back here.</p>  <p>The logging API for Application Insights is really simple.</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">   <div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">     <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">ClientAnalyticsChannel.Default.LogEvent(<span style="color: rgb(0, 96, 128);">&quot;MyCategory/MyEvent&quot;</span>);</pre>
<!--CRLF--></div>
</div>

<p>This will log an event “MyEvent” that will be categorised under the title “MyCategory”.&#160; You may have many event categories that you want to log across your app and you unhandled exception events will just be another category.&#160; You can choose what you want to call it, but for this example we are just using ‘Exceptions’ as the category name. You’ll need to call this code from two places, the UnhandledException handler and the UnobservedTaskException handler although you can use a different category name to separate these out.</p>

<p>The event name is slightly more problematic. You want to have a unique event captured for each execution path that leads to an exception.&#160; In order to do this you can generate a hash based on the stack trace of the exception.&#160; Don’t forget that, in this world of async/await and AggregateException, you’ll need to include the child elements of the AggregateException and their InnerException as well. </p>

<p>The following method should give you a string that when hashed results in a unique id by which to classify your exception.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; height: 240px; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">
    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">string</span> GetFullDetail(Exception ex)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">{</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: rgb(0, 0, 255);">string</span> thisException = <span style="color: rgb(0, 0, 255);">string</span>.Format(<span style="color: rgb(0, 96, 128);">&quot;{0}: {1} - {2}&quot;</span>, ex.GetType().Name, ex.Message, ex.StackTrace);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: rgb(0, 0, 255);">if</span> (ex.InnerException != <span style="color: rgb(0, 0, 255);">null</span>)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        <span style="color: rgb(0, 128, 0);">// Recursively get inner exception details</span></pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 0, 255);">string</span> innerExceptionDetails = GetFullDetail(ex.InnerException);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 0, 255);">if</span> (<span style="color: rgb(0, 0, 255);">string</span>.IsNullOrEmpty(innerExceptionDetails))</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">            thisException = <span style="color: rgb(0, 0, 255);">string</span>.Format(<span style="color: rgb(0, 96, 128);">&quot;{0}\n\nINNER: {1}&quot;</span>, thisException, innerExceptionDetails);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    var aggregateException = ex <span style="color: rgb(0, 0, 255);">as</span> AggregateException;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">if</span> (aggregateException != <span style="color: rgb(0, 0, 255);">null</span> &amp;&amp; aggregateException.InnerExceptions != <span style="color: rgb(0, 0, 255);">null</span>)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 0, 255);">int</span> count = 1;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">        <span style="color: rgb(0, 0, 255);">if</span> (var aggregateInner <span style="color: rgb(0, 0, 255);">in</span> aggregateException.InnerExceptions)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">        {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">            <span style="color: rgb(0, 128, 0);">// Don't include the aggregate that's just a duplicate of the inner.</span></pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">            <span style="color: rgb(0, 0, 255);">if</span> (aggregateInner != ex.InnerException)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">            {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                <span style="color: rgb(0, 128, 0);">// Recursively get aggregate inner exceptions</span></pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">                <span style="color: rgb(0, 0, 255);">string</span> aggregateInnerExceptionDetails = GetFullDetail(aggregateInner);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                <span style="color: rgb(0, 0, 255);">if</span> (!<span style="color: rgb(0, 0, 255);">string</span>.IsNullOrEmpty(aggregateInnerExceptionDetails))</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">                {</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                    thisException = <span style="color: rgb(0, 0, 255);">string</span>.Format(<span style="color: rgb(0, 96, 128);">&quot;{0}\n\nAGGREGATE({1}): {2}&quot;</span>, thisException, count, aggregateInnerExceptionDetails);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">                }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">            }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">            </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">            count++;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">        }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    }</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: rgb(0, 0, 255);">return</span> thisException;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">}</pre>
<!--CRLF--></div>
</div>

<p>By calling this method where you handle your exceptions you can use it as the event id when you call the logging code.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <div id="codeSnippet" style="padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">
    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;"><span style="color: rgb(0, 0, 255);">private</span> <span style="color: rgb(0, 0, 255);">static</span> <span style="color: rgb(0, 0, 255);">void</span> HandleException(Exception ex)</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">{</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: rgb(0, 0, 255);">string</span> exceptionDetail = GetFullDetails(ex);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    <span style="color: rgb(0, 0, 255);">string</span> hashCode = exceptionDetail.GetHashCode().ToString();</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    Dictionary&lt;<span style="color: rgb(0, 0, 255);">string</span>, <span style="color: rgb(0, 0, 255);">object</span>&gt; dimensions = <span style="color: rgb(0, 0, 255);">new</span> Dictionary&lt;<span style="color: rgb(0, 0, 255);">string</span>, <span style="color: rgb(0, 0, 255);">object</span>&gt;();</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    dimensions.Add(<span style="color: rgb(0, 96, 128);">&quot;HashCode&quot;</span>, hashCode);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    dimensions.Add(<span style="color: rgb(0, 96, 128);">&quot;StackTrace&quot;</span>, exceptionDetail);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    dimensions.Add(<span style="color: rgb(0, 96, 128);">&quot;Type&quot;</span>, ex.GetType().ToString());</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    dimensions.Add(<span style="color: rgb(0, 96, 128);">&quot;Message&quot;</span>, ex.Message);  </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">    <span style="color: rgb(0, 0, 255);">string</span> eventMessage = <span style="color: rgb(0, 0, 255);">string</span>.Format(<span style="color: rgb(0, 96, 128);">&quot;Exception/{0}/{1} - {2}&quot;</span>, </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">                                         Assembly.GetExecutingAssembly().GetName().Version.ToString(4),      </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">                                         detail.HashCode, </pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">                                         ex.Message);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">&#160;</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">    ClientAnalyticsChannel.Default.LogEvent(eventMessage, dimensions);</pre>
<!--CRLF-->

    <pre style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: &quot;Courier New&quot;, courier, monospace; font-size: 8pt; direction: ltr; background-color: white;">}</pre>
<!--CRLF--></div>
</div>

<p>The method above is doing three things.&#160; </p>

<ol>
  <ol>
    <li>Calling out first method to generate a unique and complete stack trace, we are then hashing this and using this as our identifier in 3.</li>

    <li>Adding dimensions for StackTrace, Type and Message, along with the HashCode.&#160; This allows us to extract the information we need to identify what is causing the crash.</li>

    <li>Constructing the ‘eventMessage’ and logging the event with Application Insights.</li>
  </ol>
</ol>

<p>You’ll see at the end where we construct the ‘eventMessage’ variable, the event log path is split into 2 categories and an identifying event.&#160; Here we are further splitting the events down by the appVersion.&#160; This makes it easier for us to focus on where the issues are in the current version of the app. Take a look at the screenshot below which makes this clearer.</p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/7750.image_2F358F60.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/7750.image_5F00_2F358F60.png"><img title="image" style="display: inline;" border="0" alt="image" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/5127.image_thumb_53C9AD95.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/5127.image_5F00_thumb_5F00_53C9AD95.png" width="404" height="206" /></a> </p>

<p>Hopefully this gives a useful insight in to how to instrument your Store Apps so as to be able to track and fix the exceptions that are occurring in them.</p>]]></content:encoded>
    </item>
    <item>
      <title>Creating a DNS Server in Azure IaaS</title>
      <link>https://docs.microsoft.com/archive/blogs/mcsuksoldev/creating-a-dns-server-in-azure-iaas</link>
      <pubDate>Tue, 04 Mar 2014 02:16:00 GMT</pubDate>
      <dc:creator><![CDATA[MCS_UK Solution Development]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/mcsuksoldev/2014/03/04/creating-a-dns-server-in-azure-iaas/</guid>
      <description><![CDATA[Scenario
I have multiple Azure Infrastructure-as-a-Service (Iaas) Virtual Machines (VMs) running...]]></description>
      <content:encoded><![CDATA[<h1>Scenario</h1>
<p>I have multiple Azure Infrastructure-as-a-Service (Iaas) Virtual Machines (VMs) running under multiple Cloud Services, within one Virtual Network. I need these VMs to resolve each other based on hostname as well as be able to resolve public websites.</p>
<p>If these VMs were all running in one cloud service, they would be able to resolve each other using Azure Name Resolution. However, for a variety of reasons, I need to run them in separate Cloud Services, which prevents me from using this.</p>
<p><a href="http://msdn.microsoft.com/en-us/library/windowsazure/jj156088.aspx">http://msdn.microsoft.com/en-us/library/windowsazure/jj156088.aspx</a></p>
<p>This leaves me with three options:</p>
<ol>
<li>Use host files to record the names of each VM</li>
<li>Use an existing external DNS server</li>
<li>Create a DNS server</li>
</ol>
<p>In this article, we'll explore the third option. Note this article may seem fairly basic to people who have a good understanding of infrastructure, but hopefully it will help people who don't.</p>
<p>Note: Azure AD is quite different from Windows AD and does not provide any functionality for DNS.</p>
<h1>Azure Setup</h1>
<p>To simulate this scenario, I have the following Azure setup&hellip;</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/7633.030414_1016_CreatingaDN1.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/7633.030414_5F00_1016_5F00_CreatingaDN1.png" alt="" /></p>
<p>Note, I actually have multiple VMs similar to Test1, each running in their own cloud service, but for simplicity I have just shown the DNS VM and another example VM.</p>
<p>&nbsp;</p>
<h1>Configuring DNS Virtual Network</h1>
<p>If this is not already configured (as per the above scenario), go the Azure Management Portal and set a DNS server to the IP of your DNS VM.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/3757.030414_1016_CreatingaDN2.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/3757.030414_5F00_1016_5F00_CreatingaDN2.png" alt="" /></p>
<h1>&nbsp;</h1>
<h1>Configuring DNS Server</h1>
<p>To add the DNS server role, remote onto the Virtual Machine you intend to use for DNS and launch Server Manager. From this, launch the "Add Roles and Features Wizard" and do the following:</p>
<ul>
<li>Before You Begin Screen: Click <strong>Next</strong> on the first screen</li>
<li>Installation Type Screen: Select the "<strong>Role-Based or Feature Based Installation</strong>" radio button. Click next.</li>
<li>Server Selection Screen: Select your local server (DNSVM) then click <strong>Next</strong>.</li>
<li>Server Roles Screen: Check the "<strong>DNS Server</strong>" tick box. When prompted to "<strong>Add features that are required for DNS Server?</strong>" click "<strong>Add Features</strong>" (ensure the management tools checkbox is also checked). Click <strong>Continue</strong> then click <strong>Next</strong>.</li>
<li>DNS Server Screen: Click <strong>Next</strong>.</li>
<li>Confirmation Screen: Click <strong>Install</strong>.</li>
<li>Results Screen: View the results page to confirm installation has been successful, then click <strong>Close</strong>.</li>
</ul>
<p>Once the DNS role is installed, to configure bring up the DNS Manager (in Server Manager, click DNS from the left hand pane, select your local server, right click and select DNS Manager)</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/4834.030414_1016_CreatingaDN3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/4834.030414_5F00_1016_5F00_CreatingaDN3.png" alt="" /></p>
<p>Within DNS manager, you now need to create a forward lookup zone. This is the domain name on which all of your servers are referenced. In my example, I'm going to use contoso.local (local is to denote that the domain name is just pertinent to the virtual network, and not a public domain name &ndash; you could use whatever domain name you like however).</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/1526.030414_1016_CreatingaDN4.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/1526.030414_5F00_1016_5F00_CreatingaDN4.png" alt="" /></p>
<p>In the new zone wizard&hellip;</p>
<ul>
<li>On the first screen, click <strong>Next</strong></li>
<li>Select the type of zone to be a "<strong>Primary Zone</strong>" click <strong>Next</strong></li>
<li>Set the zone name to be your domain (e.g. contoso.local). Click <strong>Next</strong></li>
<li>Accept the defaults on the "zone file" screen, click <strong>Next</strong></li>
<li>IMPORTANT: On the dynamic update screen, ensure that the radio button for "<strong>Allow both nonsecure and secure dynamic updates</strong>" is checked. This is so new VMs can automatically register. Click <strong>Next</strong>.</li>
<li>Review the settings and click <strong>Finish</strong>.</li>
</ul>
<p>You should end up with the following</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/5342.030414_1016_CreatingaDN5.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/5342.030414_5F00_1016_5F00_CreatingaDN5.png" alt="" /></p>
<p>&nbsp;</p>
<h1>Setting the DNS Suffix on all VMs</h1>
<p>The final configuration step is to ensure that all VMs (including the DNS VM) use a DNS suffix that matches your new forward lookup zone.</p>
<p>From the Server Manager, click "Local Server" in the left hand pane, then click the "Computer Name" link to launch the In the System Properties dialog.</p>
<ul>
<li>In the System Properties dialog, click <strong>Change</strong></li>
<li>In the subsequent "Computer Name / Domain Changes" dialog, click the <strong>More</strong> button.</li>
<li>Finally set the DNS suffix to match the forward lookup zone (created on your DNS server). Click <strong>Ok </strong>to close dialog boxes and allow the machine to reboot.</li>
</ul>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/7002.030414_1016_CreatingaDN6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/7002.030414_5F00_1016_5F00_CreatingaDN6.png" alt="" /></p>
<p>Repeat on every Virtual Machine.</p>
<p>&nbsp;</p>
<h1>Verify Everything's Worked</h1>
<p>To verify everything's worked, remote onto the DNS VM and launch the DNS Manager. Expand your forward lookup zone. You should see all of your VMs under this (the VMs would have automatically registered as we set our zone to "Allow both nonsecure and secure dynamic updates")</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/0412.030414_1016_CreatingaDN7.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/0412.030414_5F00_1016_5F00_CreatingaDN7.png" alt="" /></p>
<p>Finally, on each machine, launch a command prompt and run <strong>NSLookup</strong> against the other VMs in your network as well as a publicly facing website. These should now successfully resolve.</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/8400.030414_1016_CreatingaDN8.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/8400.030414_5F00_1016_5F00_CreatingaDN8.png" alt="" /></p>
<p>&nbsp;</p>
<p>Footnote: By default, root hints are configured on the DNS server. This means you can resolve external sites also with no further action:</p>
<p><img src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/01/34/14/metablogapi/6862.030414_1016_CreatingaDN9.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-01-34-14-metablogapi/6862.030414_5F00_1016_5F00_CreatingaDN9.png" alt="" /></p>
<p>Written by <a href="http://blogs.msdn.com/b/mcsuksoldev/archive/tags/rob+nowik/default.aspx">Rob Nowik</a></p>]]></content:encoded>
    </item>
  </channel>
</rss>