<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Doron&#039;s .NET Space</title>
	<atom:link href="http://blogs.microsoft.co.il/dorony/feed/" rel="self" type="application/rss+xml" />
	<link>http://blogs.microsoft.co.il/dorony</link>
	<description>A .NET Blog by Doron Yaacoby</description>
	<lastBuildDate>Wed, 07 Sep 2016 05:19:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>https://wordpress.org/?v=5.0.2</generator>
	<item>
		<title>4 Tips for Starting a New Dev Job</title>
		<link>http://blogs.microsoft.co.il/dorony/2016/09/04/4-tips-for-starting-a-new-dev-job/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2016/09/04/4-tips-for-starting-a-new-dev-job/#comments</comments>
		<pubDate>Sun, 04 Sep 2016 09:50:20 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
		
		<guid isPermaLink="false">http://blogs.microsoft.co.il/dorony/?p=2786429</guid>
		<description><![CDATA[About 2 months ago I started a new job. After almost six years at Ginger, I started a new gig at Forter, and have been having a blast there in the past few weeks. It also got me thinking quite a lot about how to learn stuff. It&#8217;s been a long time since my mind [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>About 2 months ago I started a new job. After almost six years at <a href="http://www.gingersoftware.com/">Ginger</a>, I started a new gig at <a href="http://www.forter.com">Forter</a>, and have been having a blast there in the past few weeks. It also got me thinking quite a lot about how to learn stuff. It&#8217;s been a long time since my mind had been at CONSTANT LEARNING mode. At Forter I have to learn:</p>
<ul>
<li>A new domain I know nothing about.</li>
<li>Technologies I know nothing about (including 4 programming languages I only have a passing knowledge in).</li>
<li>Huge codebases I know nothing about.</li>
<li>People in the company: their names, roles. Whom should I ask what at any given situation?</li>
</ul>
<p>Here are a few tips I gathered from my experience at my new job.</p>
<h3>1) Ask questions, but&#8230;</h3>
<p>You should be asking a lot of questions to gain the knowledge you need. Don&#8217;t be shy to ask things like &#8216;What does this term mean?&#8217;, &#8216;Who was this person and what is her role in the company?&#8217;, and of course &#8216;Why can&#8217;t I get this to run?&#8217;. But there&#8217;s a but here, there&#8217;s a way to ask questions as well:</p>
<p>&#8211; Don&#8217;t ask about everything you don&#8217;t immediately understand. Some things you can pretty easily find out on your own. There&#8217;s a lot to learn in investigating by yourself how that thing works.</p>
<p>&#8211; But don&#8217;t spend days investigating a question when someone can answer it for you in two minutes.</p>
<p>&#8211; Ask different people. Even the nicest person has his own job to do, and your questions can interrupt his flow. Also, getting the perspective of multiple people is important.</p>
<p>&#8211; Keep a list of things you don&#8217;t understand. Try to cross them off one by one by either finding out yourself, or asking a teammate. I put there things like terms I don&#8217;t understand, questions about why things were done a certain way and even questions about operating my mac (hey, I&#8217;m a Windows guy) which I wanted to google when I had the chance. Now, whenever I have a moment (e.g. running a long integration test) I try to cross something off the list.</p>
<h3>2) Don&#8217;t judge, listen</h3>
<p>As an experienced dev you feel that you bring a lot to the table, and it can be hard to resist the urge to tell teammates that some code is ugly, or that a system should have been built in a completely different way. Instead, ask &#8216;why is this piece of code complex&#8217;? Or, &#8216;what were you concerned about when you decided to build the system this way?&#8217; The answer should teach you a lot, and you&#8217;d be surprised how much more open and candid people can be when approached in a kind, not judging manner. Many times things are the way the are for a good reason. And even when there isn’t one, remember, your old company had a lot of ugly code, patches and hacks as well, left by years of pressure and compromises. Instead of judging, try to understand the context and the history involved.</p>
<h3>3) Ask everyone what they&#8217;re working on</h3>
<p>This has been incredibly useful to me. Whenever I meet a teammate in the kitchen I ask them what they&#8217;re working on. They were always happy to talk about this, and the gain for me is pretty great:</p>
<ul>
<li>They usually have to explain the purpose of parts of the system, in order for me to understand their current task. Great for crossing things off the &#8216;things I don&#8217;t understand&#8217; list!</li>
<li>I get to learn the role of this person in the team, so when something comes up later, I know who&#8217;s the expert on what.</li>
<li>I become friendlier with this teammate, which brings me to&#8230;</li>
</ul>
<h3>4) Be social</h3>
<p>It&#8217;s easy to drown in your own tasks when you&#8217;re new. Things can be overwhelming, and as an experienced dev you might feel you need to prove yourself right away and complete a lot of tasks quickly. So when they ask you out to lunch you might think it&#8217;s better if you just munch on something in front of your screen. Don&#8217;t do that. Really, your first weeks at work are not only about learning technologies and systems, they&#8217;re also about creating personal connections with the people you work with. Eat lunch with teammates every day, ask them a little about their personal lives, tell them about yours. Make friends. It will make your time at the new job much jollier.</p>
<p>One final note: Beginnings are hard. Take it easy and remember that no one expects you to change the world in your first month or two. Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2016/09/04/4-tips-for-starting-a-new-dev-job/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Beware of .NET 4.6 Workstation GC</title>
		<link>http://blogs.microsoft.co.il/dorony/2015/08/08/beware-of-net-4-6-workstation-gc/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2015/08/08/beware-of-net-4-6-workstation-gc/#respond</comments>
		<pubDate>Sat, 08 Aug 2015 08:33:10 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[.NET 4.6]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[DEV]]></category>
		<category><![CDATA[NUnit]]></category>
		<category><![CDATA[ReSharper]]></category>
		<category><![CDATA[VS2015]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/dorony/?p=2786427</guid>
		<description><![CDATA[TL;DR: Changes in the .NET 4.6 Workstation GC has made it much slower for us. We had to make sure our tests are using the Server GC mode. VS 2015 came out and we happily upgraded. Everything worked great, except for one thing: our integration tests started to run slowly. Like 10 times slower. The [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><em><strong>TL;DR</strong>: Changes in the .NET 4.6 Workstation GC has made it much slower for us. We had to make sure our tests are using the Server GC mode.</em></p>
<p>VS 2015 came out and we happily upgraded. Everything worked great, except for one thing: our integration tests started to run slowly. Like 10 times slower. The thing is, the same code, when not running under the NUnit process, worked just fine. Something was afoot.</p>
<p>After much investigation and profiling, we discovered the root cause: GC. Our integration tests run our entire system start-up process, which allocates a few gigs of caches. Ever since installing VS 2015, and .NET 4.6 with it, allocating all this RAM took a much longer time, due to GC. But, and this is a really important but, this doesn’t happen if you use <a href="https://msdn.microsoft.com/en-us/library/ms229357%28v=vs.110%29.aspx?f=255&amp;MSPPError=-2147217396">Server GC</a> mode, which we thought we did. Our unit tests were running under the Resharper tests runner process, which didn’t respect the <em>&lt;runtime&gt; </em>config section in our IntegrationTests app.config. That means that we were actually using workstation GC in our integration tests since forever, but didn’t notice it until .NET 4.6 came and made things much slower.</p>
<p>The solution to all this was forcing the Resharper test runner (or whatever process is running your tests) to use the server GC mode. I did this by opening this folder: <strong>C:\Users\YouUserName\AppData\Local\JetBrains\Installations\ReSharperPlatformVs14</strong>, and editing the file <strong>JetBrains.ReSharper.TaskRunner.CLR45.x64.exe.config. </strong>Here I just added <strong>&lt;gcServer enabled=&#8221;true&#8221; /&gt; </strong>under the runtime section. Now, you can either force Resharper to always use CLR 4.5 &amp; x64 in the options (which is what we did), or do the same for all other <strong>JetBrains.ReSharper.TaskRunner </strong>config files.</p>
<p>This is not an ideal solution. We would have to remember to keep editing these files every time we reinstall ReSharper. Also, I can’t really explain what has made things so much worse in the new workstation GC. I guess time will tell.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2015/08/08/beware-of-net-4-6-workstation-gc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Beware of the Swift String</title>
		<link>http://blogs.microsoft.co.il/dorony/2015/04/10/beware-of-the-swift-string/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2015/04/10/beware-of-the-swift-string/#respond</comments>
		<pubDate>Fri, 10 Apr 2015 16:10:54 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[Swift]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/dorony/?p=2786425</guid>
		<description><![CDATA[I have to tell you, for a company that prides itself in delivering polished, high quality products, Apple has really dropped the ball with Swift 1.0. Before the recently released Swift 1.2, it was a nightmare platform to be developing in. My main issues with it were: Compile times are so slow, that every time [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I have to tell you, for a company that prides itself in delivering polished, high quality products, Apple has really dropped the ball with Swift 1.0. Before the recently released Swift 1.2, it was a nightmare platform to be developing in. My main issues with it were:</p>
<ol>
<li>Compile times are so slow, that every time I compiled I died a small death. Before 1.2 they had no incrmental build, so every file I changed, I had to wait like 5 minutes for the entire project the build. It literally meant that every feature I wanted to develop took me 5 times more than it should have.</li>
<li>XCode support for it was crappy, without basic features such as a rename refactoring.</li>
<li>Compiling with optimizations (-o flag) was extremely buggy, resulting sometimes in compiled code that was just wrong, especially in code with lots of closures. But compiling without optimizations meant your code was extremly slow.</li>
<li>Even with optimizations, Swift 1.0 had really, really crappy peformance. The dictionary data structure, in particular, was so slow, that I simply had to avoid it everywhere, using NSMutableDictionary or even arrays if I could. I haven’t tested it on Swift 1.2, but I pray it is much faster now.</li>
<li>No Exceptions. Write once, crash everywhere.</li>
<li>Unlike most other programming languages these days, Swift is not open source. Want to look at that Dictionary code? See how you could use it better? Well, you can’t, and you won’t, ever.</li>
</ol>
<p>But the issue I want to talk about today is the Swift String type. The language designers had decided on a very intresting approach here, they made the string characters not constant in size. As you know, Java or C# a String is basiclly an array of two-byte UTF-16 characters. So for the string “I love emojis <img src="https://s.w.org/images/core/emoji/11/72x72/263a.png" alt="☺" class="wp-smiley" style="height: 1em; max-height: 1em;" />” the smiley there would be represented by two separate characters. Not so in Swift, in which the String type was designed to handle <a href="http://en.wikipedia.org/wiki/UTF-16">unicode surrogates</a> in a more elegant matter, and the emoji would be considered just one character. </p>
<p>In an ideal world, this would be a Good Thing. But in a world where every millisecond counts, this presents a performance issue. How do you access the 5th character in a Swift string? Well, you can’t use an indexer because of the variable character length. You have to iterate over the characters until you reach the 5th one. And that’s pretty slow. How do you know the string length? Same problem, an O(n) operation. So although the Swift string is more ‘correct’ than the Java/C# implementation, if you don’t pay attention, and if you do a lot of string manipulation like we do, it can kill the peformance of your app. And who knows? Maybe that piece of code you’re writing will never ever have to handle emojis or surrogate characters (because you’re using only English dictionary words or whatever). In this case you’re writing slower code for no reason at all.</p>
<p>Fortunately, there’s a workaround. You can use the String’s <strong>utf16 </strong>property to treat it as a UTF-16 string. So str.utf16[5] will get you the 5th character quickly. Even iteration on str.utf16 is much faster (at least in Swift 1.0) than iterating the String characters themselves. This tells me that the underlying structure is still an array of UTF-16 characters, but I can’t say for sure as the Swift is not open source.. However, there are some caveats. </p>
<ol>
<li>str.utf16[5] has a type of UInt16. So if you want to check if it is a dot (‘.’), you have to use something like “.”.utf16[0], which is fugly.</li>
<li>If you want to convert str.utf16[5] back to a string, you can use “\(UnicodeScalar(myUInt16))”. However, this code will CRASH your app if this is the first half of an emoji, or in other words, a non valid unicode code point. And as I said, there are no exceptions in Swift, so you can’t try-catch it. You have to roll your own IsValidUnicodeCodePoint method, based on <a href="https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html">this definition</a>. Or just copy Java’s <a href="http://docs.oracle.com/javase/7/docs/api/java/lang/Character.html#isSurrogate(char)">Character.isSurrogate</a> method, which is what I did.</li>
</ol>
<p>To conclude, I find this design choice of the Swift string to be interesting, but weird. They are optimizing for 1% of the cases, hurting peformance for the other 99%. There is a workaround, but it is not pretty. But hey, the language is young, so maybe in 1.3?</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2015/04/10/beware-of-the-swift-string/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Scala Performance Tips on Android</title>
		<link>http://blogs.microsoft.co.il/dorony/2014/10/07/scala-performance-tips-on-android/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2014/10/07/scala-performance-tips-on-android/#respond</comments>
		<pubDate>Tue, 07 Oct 2014 18:40:07 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/dorony/?p=2786417</guid>
		<description><![CDATA[Our team has been developing an NLP library, used by Ginger Page, using Scala. Now, mostly, things have been really great. Scala allows us to go very fast, and allows us to develop the app’s NLP needs in a way that Java never could have. But, as all things in life, nothing good ever comes [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Our team has been developing an NLP library, used by <a href="https://play.google.com/store/apps/details?id=com.gingersoftware.android.keyboard&amp;hl=en">Ginger Page</a>, using Scala. Now, mostly, things have been really great. <span class="GINGER_SOFTWARE_mark" id="4637cc9a-9501-4d30-af1e-eedc3b142764">Scala</span> allows us to go very fast, and allows us to develop the app’s NLP needs in a way that Java never could have. But, as all things in life, nothing good ever comes free. We’ve noticed that our app is suffering from many GC interruptions, hurting performance. I went to investigate, and this is my story.</p>
<p><strong>Benchmark on a mobile device</strong></p>
<p>Well, if you’re like us and developing a Scala library to be used with an existing app, it is useful to benchmark your lib externally. Usually performance bottlenecks that you’ll <span class="GINGER_SOFTWARE_mark" id="97aa22f4-ca3b-4285-9e1f-251517675301">solve</span> after running a benchmark from <span class="GINGER_SOFTWARE_mark" id="fe83e30e-bd9d-4a73-832f-e16c9b4fcd5c">command line</span> will translate to your app, and it is <em>so </em>much easier to benchmark on your PC and not on a mobile device. But the word ‘usually’ there is important. The HotSpot JVM and Dalvik (=Android’s VM) are quite different beasts, and memory constraints on your mobile device are also very different.</p>
<p>Therefore, I found it useful to build a standalone app in order to test my library’s performance. It has one button, which I programmed to call my library in different scenarios. It prints out how long it took to run the scenario (Side note: it was surprising to find out that my PC is ~100 times faster than my Nexus 4, which means that every 1 millisecond I measured on my PC is a whopping 100ms on mobile!).</p>
<p><strong>Beware of the GC</strong></p>
<p>After I built a demo app, I started clicking my big “TEST PERF” button, and noticed the printouts on my <span class="GINGER_SOFTWARE_mark" id="64afbe67-8ce6-44cc-9174-6954c3d712c9">logcat</span> (you should know that calls to “<span class="GINGER_SOFTWARE_mark" id="8e4721f8-c8a6-435f-ae92-94089c9dc3ba">println</span>” from Scala appear there (as Log<span class="GINGER_SOFTWARE_mark" id="5bbc9183-94e7-4931-8717-ed4abea8b210">.</span><span class="GINGER_SOFTWARE_mark" id="ed3adcef-2e25-4055-8cf5-b765ee0cba22">i</span>), so it is useful to print out timing information from within your Scala code). I immediately noticed many messages, similar to this:</p>
<p><code><strong>GC_FOR_ALLOC freed 362K, 13% free 4116K/4688K, paused 181ms, total 182ms</strong></code></p>
<p><span style="font-family: Calibri">This means that the GC kicked in, and paused my app for 181ms, which is A LOT. But hey, you may ask, it seems the GC points out that my <span class="GINGER_SOFTWARE_mark" id="0971b48c-ab33-4150-bba1-4544a428fe01">heap</span> is 4688K, which is a lot less than my <span class="GINGER_SOFTWARE_mark" id="10c607c2-d91d-459f-98b8-e74a0fae1d3a">app’s</span> heap size limit! Well, Dalvik doesn’t allocate a very big heap for your app initially. <span class="GINGER_SOFTWARE_mark" id="125781cf-3d89-4517-bc0f-057165e56c65">It grows it</span> slowly. And before it grows it, it will attempt to free up memory. Hence, the above depressing message. How do we deal with this? Well, the best thing to do is try to allocate less memory! Let’s try that then.</span></p>
<p><strong>Analyzing your <span class="GINGER_SOFTWARE_mark" id="f8259ba1-95c4-4601-843f-b8c5ed6a73a4">heap</span></strong></p>
<p>Using the Android DDMS, or in my case, the built-in Intellij plugin for Android, you can dump your device’s heap. I did so after clicking the “TEST PERF” button a couple of times, but before a GC was triggered. This allows me to check out the temporary objects I created in a profiler. I’m using <a href="http://www.yourkit.com/">YourKit</a> profiler, which is a paid one, but the resulting <span class="GINGER_SOFTWARE_mark" id="28dc372b-4be9-4692-9a8d-5087a74abe0d">hprof</span> file (which IntelliJ helpfully converts to the standard format, if you’re a DDMS user you have to use the <a href="http://developer.android.com/tools/help/hprof-conv.html"><span class="GINGER_SOFTWARE_mark" id="819df5f8-29ad-4eec-bf59-bb40240e41fb">hprof</span>&#8211;<span class="GINGER_SOFTWARE_mark" id="36dd8af4-b83c-478d-b94d-f4af7d49ed5b">conv</span></a> command line) can be viewed in any decent profiler, I believe. I started checking out the objects which are unreachable from the GC root – these are the temporary objects that the GC will collect, and my main problem. I came up with a few conclusions, which I think will be useful to any Scala on Android <span class="GINGER_SOFTWARE_mark" id="db76521f-05b3-40e3-bb33-324cc9d946d2">developer</span>.</p>
<p><strong>The Scala tax</strong></p>
<p><span class="GINGER_SOFTWARE_mark" id="f7438c3d-f26c-4078-b588-a44d810e5dc2">Scala</span> loves to create short lived objects. Android and Dalvik don’t like these so much. But not all is lost, Scala is still extremely usable under these conditions, you just have to be careful in how you use it.</p>
<p><em><strong>Vectors – careful with those</strong></em></p>
<p><a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Vector">Vector</a> is the default <a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.IndexedSeq">IndexedSeq</a> implementation, and it is a great data structure, in fact our “go to” data structure usually. But you need to be careful with it:</p>
<ol>
<li>The Vector will allocate an Object<span class="GINGER_SOFTWARE_mark" id="139ede13-92c2-46bf-ac01-76d5de987d66">[</span>32] array to hold a single item. That’s a waste on our low memory machine. Consider using Arrays instead of Vectors where appropriate to overcome this issue.</li>
<li>Using <em>IndexedSeq<span class="GINGER_SOFTWARE_mark" id="8a37d6e7-e507-4e2b-8be4-15ee82bab1bb">(</span>) </em>to create an empty vector will create a redundant Object<span class="GINGER_SOFTWARE_mark" id="950e7f50-d471-40af-a406-061662e24d9b">[</span>32] array. You should use <em>IndexedSeq<span class="GINGER_SOFTWARE_mark" id="219126e7-2f69-4163-b5a4-2d9946397a99">.</span>empty</em> or <em>Vector<span class="GINGER_SOFTWARE_mark" id="af3aabd9-200c-49e4-b416-88d4c50f20f8">.</span>empty</em> instead.</li>
<li>Vector<span class="GINGER_SOFTWARE_mark" id="1b7a3f7c-a4bf-4724-9256-1a6bf83e3e5a">.</span>tail is more costly than List<span class="GINGER_SOFTWARE_mark" id="7b917d94-b3b1-44cf-b416-9f861bb3ffc4">.</span>tail, as it creates a new Vector. If you have a recursive function that uses.<span class="GINGER_SOFTWARE_mark" id="83603e2c-93bb-4068-b2fd-2346f2da11df">head</span> and<span class="GINGER_SOFTWARE_mark" id="000f4898-ec24-478f-b7f3-04f0160a7e41"> .</span><span class="GINGER_SOFTWARE_mark" id="21e16b03-306e-4ece-b881-e639b5ed0d26">tail</span> (a common pattern in Scala and other functional languages), consider using a list, or access your vector using the indexer (e.g. <span class="GINGER_SOFTWARE_mark" id="2e9f0fb8-4d10-4abe-8068-8ac4ef1408e2">myVector</span><span class="GINGER_SOFTWARE_mark" id="89317002-bcd6-41a7-9690-830e221923b0">(</span>5)).</li>
</ol>
<p><strong><em>Method chaining – embrace<span class="GINGER_SOFTWARE_mark" id="07d5edc5-2516-42bc-a9f8-c48543ddb35d"> .</span><span class="GINGER_SOFTWARE_mark" id="976d140a-f6bf-4a51-9eb9-f92f7e9b2fc9">view</span></em></strong></p>
<p>So you have a vector, an array or a list, and you’re doing something like <em><strong>vector<span class="GINGER_SOFTWARE_mark" id="9fdff8d9-982a-47a5-8d49-0474b3e0e7a2">.</span>map<span class="GINGER_SOFTWARE_mark" id="c5743609-c262-4197-93a2-79e6e02843d3">(</span>…)<span class="GINGER_SOFTWARE_mark" id="4780de33-8a7e-483c-a66f-be5885eebbe5">.</span>filter<span class="GINGER_SOFTWARE_mark" id="e37d7c95-e11b-40ba-a994-66115fbc9d35">(</span>…)<span class="GINGER_SOFTWARE_mark" id="a1b5ab99-5443-4a9d-ba46-da918a5cd87d">.</span>map<span class="GINGER_SOFTWARE_mark" id="c4dfec2b-b47f-4d9a-895d-4e781bf180ee">(</span>…)</strong>. </em>Bad idea. In this example, you’ll be allocating a temporary vector after each method call. Instead, do a <em><strong>vector<span class="GINGER_SOFTWARE_mark" id="c531bb4b-3dd0-45b5-9a53-9ce0a8813ae6">.</span><span style="background-color: #ffff00"><span class="GINGER_SOFTWARE_mark" id="af831ce6-d1a6-49e3-bf43-19582a429bcd">view</span><span class="GINGER_SOFTWARE_mark" id="8c5eb1d8-1336-46d0-8709-4fc542db009c">.</span></span>map<span class="GINGER_SOFTWARE_mark" id="b7f51d58-bd59-49f3-b9c9-455e52f2d73a">(</span>…)<span class="GINGER_SOFTWARE_mark" id="9bf03c14-53df-4d03-87ed-a439dc2897ec">.</span>filter<span class="GINGER_SOFTWARE_mark" id="4a003bd1-92b1-4c3f-93d8-0a89de31f1fb">(</span>…)<span class="GINGER_SOFTWARE_mark" id="07a5b9c8-908d-4eed-ab6a-89cdfba89c8f">.</span>map<span class="GINGER_SOFTWARE_mark" id="150da5d5-231d-45b7-acb8-e90151f0552d">(</span>…)<span class="GINGER_SOFTWARE_mark" id="a918a8b3-de4e-410e-9467-f67430e4f6b2">.</span><span class="GINGER_SOFTWARE_mark" id="f11efc64-67da-40ac-83e8-eaa037596b1a">toVector</span>. </strong></em>This will make sure you only allocate one vector, at the end of the chain.</p>
<p><em><strong>Boxing is your enemy</strong></em></p>
<p>Oh man, how I wish the JVM had the CLR’s generics and value types support. Unfortunately, it does not. This means that your beautiful generic function, which can work on any type, will probably cause <a href="http://en.wikipedia.org/wiki/Object_type_(object-oriented_programming)#Boxing">boxing</a> when used with primitive types. You might see it in your profiler <span class="GINGER_SOFTWARE_mark" id="ca09a8c1-cfe9-4a26-91e9-b32a574c2a4e">as</span> <em><span class="GINGER_SOFTWARE_mark" id="68b94ba5-0f84-49b9-8f9b-f69a271cbf14">scala</span><span class="GINGER_SOFTWARE_mark" id="147e1e7e-2e55-428f-87f6-cc26f6997d18">.</span>runtime<span class="GINGER_SOFTWARE_mark" id="4852908d-1b7e-4766-8433-963d0493bc24">.</span>BoxesRunTime<span class="GINGER_SOFTWARE_mark" id="374dcf99-d628-44e1-bb03-718136947150">.</span><span class="GINGER_SOFTWARE_mark" id="81700cc9-df40-47ea-bc5a-43acd2771aff">boxToInteger</span><span class="GINGER_SOFTWARE_mark" id="9b313057-1e35-4532-99e3-c87889ce66d8">(</span><span class="GINGER_SOFTWARE_mark" id="1219e1f2-b89c-446b-a893-5282e9a08c6f">int</span>) </em>or similar calls. Here’s some tips on avoiding boxing:</p>
<ul>
<li>You can try using the @<a href="http://www.scala-notes.org/2011/04/specializing-for-primitive-types/">specialized</a> annotation on your generic method or class. It doesn’t work in every case, and in one critical place in my code I had to…</li>
<li>Copy &amp; paste some functions to work directly with an Integer. <img class="wlEmoticon wlEmoticon-sadsmile" style="border-style: none" alt="Sad smile" src="http://blogs.microsoft.co.il/dorony/wp-content/uploads/sites/333/2014/10/wlEmoticon-sadsmile.png" /></li>
<li>Beware of using <a href="http://www.scala-lang.org/api/current/index.html#scala.Option">Option</a><span class="GINGER_SOFTWARE_mark" id="b950398b-95ec-4743-9271-f1019173cb86">[</span>Int]. It will box your integer. I have a lot of these, and haven’t yet decided the best approach. I might change my code to return –1 as the “None” value, or consider using this <a href="http://jnordenberg.blogspot.se/2013/03/a-more-efficient-option.html">alternative Option class</a>.</li>
<li>Some lambda expressions, which are based on classes that are not <a href="http://stackoverflow.com/questions/5477675/why-are-so-few-things-specialized-in-scalas-standard-library">specialized</a>, will cause your primitive to box. You might want to skip the lambdas in this case.</li>
</ul>
<p><strong><em>While instead of <span class="GINGER_SOFTWARE_mark" id="887a697a-4c9c-476a-8510-0b5d0705eb06">for</span></em></strong></p>
<p><span class="GINGER_SOFTWARE_mark" id="a61b22f0-cbea-45d0-b399-de84b7fe23fd">Scala</span> for loops might not be what you think they are. They are more like C# Linq expressions than C# for or <span class="GINGER_SOFTWARE_mark" id="be41179a-db2a-4e51-97de-59793eeedf2b">foreach</span>. They get translated to <em>map<span class="GINGER_SOFTWARE_mark" id="f8b0a1f2-2293-419b-9add-fd97f0105c0b">(</span>)</em> and <em><span class="GINGER_SOFTWARE_mark" id="0b347fad-65a5-4566-815e-be156e7be8cc">withFilter</span><span class="GINGER_SOFTWARE_mark" id="8333095b-965d-4f17-9552-7c0534bf801a">(</span>)</em> calls with anonymous function <span class="GINGER_SOFTWARE_mark" id="66ee7919-99f8-43ef-b6cf-8fac675ad59b">for</span> the loop body. This means that code like:</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"><span class="GINGER_SOFTWARE_mark" id="01a9370d-59d0-4c7e-ba24-ea65236b4ae4">for</span></span><span class="GINGER_SOFTWARE_mark" id="feb17c22-478a-4a24-a564-f2a427bc1b4d">(</span>index &lt;- 0 until s<span class="GINGER_SOFTWARE_mark" id="261d3a11-b53d-4a58-9a02-da0e344b49cc">.</span>size<span class="GINGER_SOFTWARE_mark" id="aee806e7-853c-4520-803c-601340741268">)</span>{
 <span style="color: #008000">//<span class="GINGER_SOFTWARE_mark" id="820789bf-26c9-49dd-8242-d67145db1f08">do</span> stuff</span>
}</pre>
<p>&nbsp;</p>
</div>
<p>Will allocate:</p>
<ul>
<li>An object for the anonymous function that represents the loop’s body</li>
<li>A <a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.Range">Range</a> object for the (0 until s<span class="GINGER_SOFTWARE_mark" id="4c519764-11df-4b53-bf0a-c8beeaf3fdf9">.</span>size) expression</li>
</ul>
<p>This can be easily replaced with a while loop that does none of the above:</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 class="GINGER_SOFTWARE_mark" id="83067318-c454-4de2-b3e7-cf52808ba596">var</span> index = 0
<span style="color: #0000ff"><span class="GINGER_SOFTWARE_mark" id="c47f0e22-3084-4433-aa36-ccaa60d5a795">while</span></span> (<span class="GINGER_SOFTWARE_mark" id="f5c2367a-f80c-4921-9210-9262a41760be">i &lt; s</span><span class="GINGER_SOFTWARE_mark" id="3358baa4-daf6-43ca-a56b-03afb09d2df2">.</span>size) {
<span style="color: #008000">//<span class="GINGER_SOFTWARE_mark" id="364c6972-c86b-49f0-be52-184309d87309">do</span> stuff</span>
 i+=1
}</pre>
<p>&nbsp;</p>
</div>
<p>Yes, this is uglier, and I don’t recommend doing it everywhere. Just in the places that hurt the most (get called most often).</p>
<p><strong><em>Beware of implicit conversions</em></strong></p>
<p>Sometimes Scala will implicitly wrap your object with another object. Say you’re calling <em><strong><span class="GINGER_SOFTWARE_mark" id="e85288a5-9d78-4282-9763-cd32944f4baa">str</span><span class="GINGER_SOFTWARE_mark" id="ed260a75-b068-4e91-8de8-c29e6d27269e">.</span><span class="GINGER_SOFTWARE_mark" id="b08e49bc-a983-4bb5-a1d0-7ff6b0901d1e">indexWhere</span><span class="GINGER_SOFTWARE_mark" id="3b17e812-c314-47a1-8fc0-cb1dc0431040">(</span>c=&gt;<span class="GINGER_SOFTWARE_mark" id="4051e3ae-7844-48a1-adee-4c54e8568bf9">c.</span><span class="GINGER_SOFTWARE_mark" id="193443a4-b7f5-4b88-a3dc-81c239112fb4">isUpper</span>)</strong></em>. Did you know that your string is being wrapped with a <a href="http://www.scala-lang.org/api/current/index.html#scala.collection.immutable.StringOps">StringOps</a> object, and your <span class="GINGER_SOFTWARE_mark" id="0ecf09f0-f067-4b17-a39d-5b494b643a40">char</span> is being wrapped with a <a href="http://www.scala-lang.org/api/current/index.html#scala.runtime.RichChar">RichChar</a> object? This might cause redundant allocations where you least expect them. In one performance critical place, I ended replacing an <em><span class="GINGER_SOFTWARE_mark" id="bcb226a7-8606-496e-840a-9fe20dd80955">indexWhere</span> </em>call <span class="GINGER_SOFTWARE_mark" id="5484a774-ea88-4a85-b19d-2c7a86e91134">with</span> a static function I created, that skipped both the StringOps conversion and the lambda expression altogether.</p>
<p><strong><em>Scala’s Map gotcha</em></strong></p>
<p>Scala’s <a href="http://www.scala-lang.org/api/current/index.html#scala.collection.Map">Map<span class="GINGER_SOFTWARE_mark" id="71906d4a-c35b-456b-b4b3-7ae398670573">.</span>get</a>, will wrap your value in an Option. Very convenient, I admit, but sometimes you just can’t afford the extra allocation. This sucks, but I had to use Java’s HashMap in one place to avoid this.</p>
<p><strong>Conclusion &amp; Disclaimer</strong></p>
<p>My suggestions are things you should pay attention to, but you should only apply them where it hurts and after you noticed them in a profiler. You don’t want to pre-optimize your code, as you’ll just end up with uglier, not necessarily faster (or more memory efficient) code. Still, you should be very aware of where your code allocates memory when running on Android. Dump you heap, and optimize away. Good luck!</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2014/10/07/scala-performance-tips-on-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Meet object-csv, a Strongly Typed CSV Helper for Scala</title>
		<link>http://blogs.microsoft.co.il/dorony/2014/05/16/meet-object-csv-a-strongly-typed-csv-helper-for-scala/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2014/05/16/meet-object-csv-a-strongly-typed-csv-helper-for-scala/#comments</comments>
		<pubDate>Fri, 16 May 2014 14:39:29 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/dorony/?p=2786414</guid>
		<description><![CDATA[Yeah, I know this is a .NET blog, but recently my team at Ginger Software ventured into some Android coding. Now, we didn’t want to use Java, and preferred something with more functional capabilities. Scala was the natural choice. One thing we use a lot in our C# projects is CSV files. They are much [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>Yeah, I know this is a .NET blog, but recently my team at <a href="http://www.gingersoftware.com/">Ginger Software</a> ventured into some Android coding. Now, we didn’t want to use Java, and preferred something with more functional capabilities. Scala was the natural choice. One thing we use a lot in our C# projects is CSV files. They are much easier to programmatically read/write than Excel files, and our analysts can still work with them as if they were Excel files. Sadly, Scala was missing a library to read/write CSV files to/from objects, which was something we sorely missed. Therefore, I set out to build our own. This is not a fully fledged framework, it is tailored to our specific needs, but can be easily modified to suit your own. It uses the <a href="https://github.com/tototoshi/scala-csv">scala-csv</a> project as a dependency, and we call it <a href="https://github.com/dorony/object-csv">object-csv</a>.</p>
<p>Let’s say you defined this case class:</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">case</span> <span style="color: #0000ff">class</span> Person (name: String, age: Int, salary: Double, isNice:Boolean = false)</pre>
<p>&nbsp;</p>
</div>
<p>You can write a collection of Person to a .csv file this way:</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">import</span> com.gingersoftware.csv.ObjectCSV._
<span style="color: #008000">//...</span>
val person1 = <span style="color: #0000ff">new</span> Person(<span style="color: #006080">"Doron,y"</span>,10,5.5)
val person2 = <span style="color: #0000ff">new</span> Person(<span style="color: #006080">"David"</span>,20,6.5)
writeCSV(IndexedSeq(person1,person2), fileName)</pre>
<p>&nbsp;</p>
</div>
<div>This will generate the following CSV file:</div>
<div></div>
<div>#Name,Age,Salary,IsNice<br />
&#8220;Doron,y&#8221;,10,5.5,false<br />
David,20,6.5,false</div>
<div></div>
<div>In a similar manner, you can also read this CSV file as a collection of Person. Note that the order of the columns in the CSV file doesn&#8217;t matter, we use the header to match each value to the correct constructor argument. This allows your files to be more flexible: <span class="GINGER_SOFTWARE_mark" id="c96acefb-9bce-46c5-9970-db33ccd53d49">add</span> columns or change their order, and your code won’t break.</div>
<div></div>
<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 class="GINGER_SOFTWARE_mark" id="1068a138-2bcd-4765-b9aa-929659819a94">val</span> <span class="GINGER_SOFTWARE_mark" id="d0521037-aefa-4e06-aad3-d09f4e97044f">peopleFromCSV</span> = <span class="GINGER_SOFTWARE_mark" id="0d610878-26bb-491f-b382-5b31401f8e4f">readCSV</span><span class="GINGER_SOFTWARE_mark" id="c92d1e80-bb3c-4d7f-8d84-847ddbea9b9a">[</span>Person<span class="GINGER_SOFTWARE_mark" id="7f5fde8f-005d-40c1-bd74-81b907a3ddf7">]</span>(<span class="GINGER_SOFTWARE_mark" id="dfa7a937-95b6-476e-8ab0-d2d236d1c16c">fileName</span>)
<span style="color: #0000ff">assert</span>(peopleFromCSV === IndexedSeq(Person(<span style="color: #006080">"Doron,y"</span>,10,5.5),Person(<span style="color: #006080">"David"</span>,20,6.5)))</pre>
<p>&nbsp;</p>
</div>
<p>Nice and simple, right? It serves our needs nicely, but it comes with some caveats:</p>
<p>1) It only works with Scala 2.11, as it uses <span class="GINGER_SOFTWARE_mark" id="c78ec462-3332-4876-85ca-bedf24aaab30">scala</span><span class="GINGER_SOFTWARE_mark" id="9518cb17-fe62-4bec-822d-b2d4ed31db89">.</span><span class="GINGER_SOFTWARE_mark" id="302ed626-3114-42aa-88c4-019bc31537d4">reflect</span> which wasn’t really stable <span class="GINGER_SOFTWARE_mark" id="270ad421-5728-4255-b420-198d866abd70">on</span> 2.10. So make sure you have set <em><strong><span class="GINGER_SOFTWARE_mark" id="d9848f70-e574-455e-8622-565698b7f0c1">scalaVersion</span><span class="GINGER_SOFTWARE_mark" id="2b09eaf6-f439-4629-a013-a2b2a89b09ea"> :</span>= &#8220;2.11.0&#8221; </strong></em>in your build<span class="GINGER_SOFTWARE_mark" id="8c2ee05a-8bce-43f1-b83c-f77d3721aea7">.</span><span class="GINGER_SOFTWARE_mark" id="abb64d1b-90ba-49eb-b8b5-74b37aa55fcb">sbt</span>.</p>
<p>2) It only works with case classes, as all the reflection stuff is based on using your case class primary constructor.</p>
<p>3) For reading, we only currently support the following data types: Int, Double, Boolean and String. We’ll probably add more as we need them. Writing works with everything, as we just<span class="GINGER_SOFTWARE_mark" id="74254aba-a03c-4763-9ff9-c084866ec26d"> .</span>toString it all.</p>
<p>4) We can only read/write CSV files with headers, and the header must begin with the comment mark (#).</p>
<p>5) The API currently doesn’t expose ways to control the type of separator used in the CSV file, but it is very easy to add (the <span class="GINGER_SOFTWARE_mark" id="254c0d67-5456-4d22-bb8b-e4d120da186f">scala</span>&#8211;<span class="GINGER_SOFTWARE_mark" id="73b53b9e-4fcb-4a68-8ee0-b12560539ea7">csv</span> project does support it).</p>
<p>6) We didn’t test it for speed, reading is likely to be slow as it uses reflection heavily.</p>
<div></div>
<div>Still <span class="GINGER_SOFTWARE_mark" id="e1848898-afd7-487c-98cc-9f3442c305d5">wanna</span> use it? Great! Just add the following to your <span class="GINGER_SOFTWARE_mark" id="43651955-9db3-481c-a56e-2983b9b97af5">sbt</span> file:</div>
<div></div>
<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 class="GINGER_SOFTWARE_mark" id="54013f78-5906-4870-b08e-b889c6c04a7e">libraryDependencies</span> += <span style="color: #006080">"<span class="GINGER_SOFTWARE_mark" id="3c9c0631-4d9c-4b50-aaa8-0a8e83ceb3ad">com</span><span class="GINGER_SOFTWARE_mark" id="59836fe4-4a92-4d3a-9ea3-ba3af15bdbdf">.</span><span class="GINGER_SOFTWARE_mark" id="b7418467-ab92-4ac2-bd0f-05f417aecfb8">gingersoftware</span>"</span> % <span style="color: #006080">"object-csv_2<span class="GINGER_SOFTWARE_mark" id="81f786f4-4c98-4556-8098-265c0b3c876d">.</span>11"</span> % <span style="color: #006080">"0.1"</span></pre>
<p>Or you can just <a href="https://github.com/dorony/object-csv">browse the code</a> and copy the classes (there are only 2) to your project. We’d appreciate any feedback, we’re pretty new to Scala development.</p>
</div>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2014/05/16/meet-object-csv-a-strongly-typed-csv-helper-for-scala/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Async Void Methods Can Crash Your Process</title>
		<link>http://blogs.microsoft.co.il/dorony/2013/10/30/async-void-methods-can-crash-your-process/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2013/10/30/async-void-methods-can-crash-your-process/#respond</comments>
		<pubDate>Wed, 30 Oct 2013 14:51:40 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[.NET 4.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[Multithreading]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/?p=2786410</guid>
		<description><![CDATA[Last time I told you an async log4net appender got me in trouble. After resolving that issue, I remained with an appender that directly implements IAppender, that looked something like this: 1: public class SplunkAppender : IAppender 2: { 3: public async void DoAppend(log4net.Core.LoggingEvent loggingEvent) 4: { 5: var clientIp = _clientIpRetriever.GetClientIp(); 6: var message [&#8230;]]]></description>
				<content:encoded><![CDATA[<p><a href="http://blogs.microsoft.co.il/blogs/dorony/archive/2013/10/16/the-case-of-the-async-log4net-appender.aspx">Last time</a> I told you an async log4net appender got me in trouble. After resolving that issue, I remained with an appender that directly implements IAppender, that looked something like this:</p>
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippet" class="csharpcode">
<div id="codeSnippetWrapper" class="csharpcode-wrapper">
<div id="codeSnippet" class="csharpcode">
<div id="codeSnippetWrapper">
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> SplunkAppender : IAppender</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>     {        </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>         <span style="color: #0000ff">public</span> async <span style="color: #0000ff">void</span> DoAppend(log4net.Core.LoggingEvent loggingEvent)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>             var clientIp = _clientIpRetriever.GetClientIp();</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>             var message = <span style="color: #0000ff">new</span> SplunkMessage(loggingEvent.Level, loggingEvent.ExceptionObject, clientIp);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>             var success = await _splunkLogger.Report(message);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>             <span style="color: #008000">//do something unimportant</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Close() { }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum12" style="color: #606060">  12:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name {get; set;}        </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum13" style="color: #606060">  13:</span>     }</pre>
<p><!--CRLF--></div>
</p></div>
<div class="csharpcode">Pretty simple, yes? Now, as you can see, I also added the client’s IP to Splunk’s report, because why not (this is a self-hosted WCF service we’re talking about)? A few hours after this was deployed to production, BOOM. A few of the servers crashed. Well, at least it’s not a deadlock this time. Still, the exception is pretty weird, and looked something like &#8211; </div>
</p></div>
</p></div>
</p></div>
</p></div>
</div>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; border-right: silver 1px solid; width: 97.5%; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> Unhandled Exception: System.Exception: Exception of type <span style="color: #006080">'System.Exception'</span> was thrown.</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>    at ConsoleApplication1.ClientIpRetriever.GetClientIp() <span style="color: #0000ff">in</span> d:\Projects\Blog\ConsoleApplication1\Program.cs:line 25</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>    at ConsoleApplication1.SplunkAppender.&lt;DoAppend&gt;d__0.MoveNext() <span style="color: #0000ff">in</span> d:\Projects\Blog\ConsoleApplication1\Program.cs:line 34</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span> --- End of stack trace from previous location <span style="color: #0000ff">where</span> exception was thrown ---</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>    at System.Runtime.CompilerServices.AsyncMethodBuilderCore.&lt;ThrowAsync&gt;b__5(Object state)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>    at System.Threading.QueueUserWorkItemCallback.WaitCallback_Context(Object state)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>    at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>    at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>    at System.Threading.QueueUserWorkItemCallback.System.Threading.IThreadPoolWorkItem.ExecuteWorkItem()</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>    at System.Threading.ThreadPoolWorkQueue.Dispatch()</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span>    at System.Threading._ThreadPoolWaitCallback.PerformWaitCallback()</pre>
<p><!--CRLF--></div>
</div>
<p>Hmm. Pretty obvious. <em>GetClientIp</em> Throws an exception, which is not caught, erm, anywhere. But wait a minute, surely log4net handles exceptions thrown by appenders, right? And even if it doesn’t it should make a single request fail, not the entire-freaking-process?!</p>
<p>Then I looked at the stack trace, which contains stuff like <em>AsyncMethodBuilderCore </em>and I realized this happens because it’s an async method. Stephen Cleary <a href="http://msdn.microsoft.com/en-us/magazine/jj991977.aspx">had this to say</a> about async void methods:</p>
<blockquote>
<p>Async void methods have different error-handling semantics. When an exception is thrown out of an async Task or async Task&lt;T&gt; method, that exception is captured and placed on the Task object. With async void methods, there is no Task object, so any exceptions thrown out of an async void method will be raised directly on the SynchronizationContext that was active when the async void method started.</p>
</blockquote>
<p>In order to simplify error handling, an async method will never throw an exception to the calling code. The exception can be observed via the created Task. Otherwise you’d have to handle in a different way the case of an exception thrown before the await call and after it. But as Stephen Cleary says above, there is simply no way to catch an exception thrown by an async void method, except for the AppDomain.UnhandledException event or something of the sort.</p>
<p>In my case, <em>GetClientIp </em>threw an exception. The calling code is an async void method, so the exception was never caught and it crashed the process. FUN. The solution? Don’t use an async void method, and if you do, make sure to catch your exceptions! I ended up with something that looked like this:</p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; height: 260px; font-family: &#39;Courier New&#39;, courier, monospace; border-right: silver 1px solid; width: 96.89%; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum1" style="color: #606060">   1:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> SplunkAppender : IAppender</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     {        </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> DoAppend(log4net.Core.LoggingEvent loggingEvent)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>             var clientIp = _clientIpRetriever.GetClientIp();</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>             var message = <span style="color: #0000ff">new</span> SplunkMessage(loggingEvent.Level, loggingEvent.ExceptionObject, clientIp);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>             SendMessageToSplunk(message);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum11" style="color: #606060">  11:</span>         <span style="color: #0000ff">private</span> async <span style="color: #0000ff">void</span> SendMessageToSplunk(SplunkMessage message)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum12" style="color: #606060">  12:</span>         {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum13" style="color: #606060">  13:</span>             <span style="color: #0000ff">try</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum14" style="color: #606060">  14:</span>             {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum15" style="color: #606060">  15:</span>                 var success = await _splunkLogger.Report(message);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum16" style="color: #606060">  16:</span>                 <span style="color: #008000">//do something unimportant</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum17" style="color: #606060">  17:</span>             }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum18" style="color: #606060">  18:</span>             <span style="color: #0000ff">catch</span>(Exception x)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum19" style="color: #606060">  19:</span>             {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum20" style="color: #606060">  20:</span>                 LogLog.Error(GetType(), <span style="color: #006080">&quot;Error in SplunkAppender.&quot;</span>, x);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum21" style="color: #606060">  21:</span>             }            </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum22" style="color: #606060">  22:</span>         }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum23" style="color: #606060">  23:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> Close() { }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: #f4f4f4"><span id="lnum24" style="color: #606060">  24:</span>         <span style="color: #0000ff">public</span> <span style="color: #0000ff">string</span> Name {get; set;}        </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; font-family: &#39;Courier New&#39;, courier, monospace; width: 100%; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; border-left-style: none; line-height: 12pt; padding-right: 0px; background-color: white"><span id="lnum25" style="color: #606060">  25:</span>     }</pre>
<p><!--CRLF--></div>
</div>
<p>The <em>DoAppend</em> method is not async anymore, so any exception will be thrown and caught in the standard way. I do still have an async void helper method, but it is protected with a try-catch clause, and so production has been stable ever since.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2013/10/30/async-void-methods-can-crash-your-process/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Case of The Async Log4Net Appender</title>
		<link>http://blogs.microsoft.co.il/dorony/2013/10/16/the-case-of-the-async-log4net-appender/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2013/10/16/the-case-of-the-async-log4net-appender/#comments</comments>
		<pubDate>Wed, 16 Oct 2013 13:34:13 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[.NET 4.5]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[log4net]]></category>
		<category><![CDATA[Multithreading]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/?p=2728776</guid>
		<description><![CDATA[It was a bad day. I was coding away happily as we started getting alerts that one of our production farms is down. Our service seemed to be stuck on each one of our servers. Requests are coming in, but no responses appear. Restarting the service helped, only to get stuck again after a while. [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>It was a bad day. I was coding away happily as we started getting alerts that one of our production farms is down. Our service seemed to be stuck on each one of our servers. Requests are coming in, but no responses appear. Restarting the service helped, only to get stuck again after a while. The logs were unhelpful, and we had to pull out <a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463009.aspx">windbg</a> to figure out what was going on. When your day starts with windbg, you know it won’t be a good one.</p>
<p>The command <em>~*e!clrstack </em>(=view stack trace of all managed threads)<em> </em>showed us that most of the threads are deadlocked in log4net’s <a href="https://github.com/apache/log4net/blob/trunk/src/Appender/AppenderSkeleton.cs">AppenderSkeleton</a> class. It looks something like this:</p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; border-right: silver 1px solid; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; width: 97.5%; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">void</span> DoAppend(LoggingEvent loggingEvent) </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">lock</span>(<span style="color: #0000ff">this</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>     {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>         <span style="color: #008000">//bla bla bla... do some stuff</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>         Append(loggingEvent); <span style="color: #008000">//method in child class</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>         <span style="color: #008000">//bla bla bla... do more stuff                </span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum9" style="color: #606060">   9:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>Lo and behold! There’s some locking here. I wasn’t even aware that log4net is locking on each call to Append, although it makes sense of course when your usual task is writing to files (one could suggest that there are better ways to approach that as well, and one would probably be right). Our own custom appender isn’t really writing to files, it sends log messages to <a href="http://www.splunk.com/">Splunk</a> (a pretty awesome system, albeit very expensive).</p>
<div id="codeSnippetWrapper" style="overflow: auto; cursor: text; font-size: 8pt; border-top: silver 1px solid; font-family: &#39;Courier New&#39;, courier, monospace; border-right: silver 1px solid; border-bottom: silver 1px solid; padding-bottom: 4px; direction: ltr; text-align: left; padding-top: 4px; padding-left: 4px; margin: 20px 0px 10px; border-left: silver 1px solid; line-height: 12pt; padding-right: 4px; max-height: 200px; width: 97.5%; background-color: #f4f4f4">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> SplunkAppender : AppenderSkeleton</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>    {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>        <span style="color: #0000ff">protected</span> <span style="color: #0000ff">override</span> async <span style="color: #0000ff">void</span> Append(log4net.Core.LoggingEvent loggingEvent)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>        {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>            var message = <span style="color: #0000ff">new</span> SplunkMessage(loggingEvent.Level, loggingEvent.ExceptionObject);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>            var success = await _splunkLogger.Report(message);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>            <span style="color: #008000">//do something with the success status, not really relevant</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>        }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>    }</pre>
<p><!--CRLF--></div>
</div>
<p>I know what you’re thinking. Why is your append method async? Well, since logging to Splunk is a networked operation, we don’t want it to be done on the current thread. So our own SplunkLogger just puts messages in a queue, and a dedicated thread will send them to Splunk. But we also want to know if and when the message was succesfully sent. Hence, an async task that only completes when the message is actually sent.</p>
<p>You’ve probably figured out right now what happended to our threads by now. If for whatever reason messages are stuck in the queue and not being sent, then the lock in DoAppend is never released! The <a href="http://msdn.microsoft.com/en-us/library/system.threading.monitor.exit.aspx">Monitor.Exit()</a> call won’t happen until the task returns, as the async/await system rightfully makes sure of that. Log calls from other threads will never be able to complete.</p>
<p>Once we figured this out, the solution was simple. Stop locking! Our SplunkLogger is thread-safe anyway, so this wasn’t required at all in the first place. Unfortunately this means we had to leave the conveinence of AppenderSkeleton and directly implement <a href="https://github.com/apache/log4net/blob/trunk/src/Appender/IAppender.cs">IAppender</a>. You lose some filters and formatting support there, but luckily for us we weren’t really using these features in this appender.</p>
<p>Less luckily for us, there were more problems with this code. More on that in the next post, stay tuned.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2013/10/16/the-case-of-the-async-log4net-appender/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Charniak Parser on Windows</title>
		<link>http://blogs.microsoft.co.il/dorony/2013/03/02/charniak-parser-on-windows/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2013/03/02/charniak-parser-on-windows/#comments</comments>
		<pubDate>Sat, 02 Mar 2013 12:31:46 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[C++]]></category>
		<category><![CDATA[NLP]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/?p=1775139</guid>
		<description><![CDATA[A while ago we wanted to choose a new natural language parser for our product. One of the strongest candidates in that area is the Charniak-Johnson parser. We ended up not choosing to use this parser for various reasons, but in the process of evaluating it we produced a nice side benefit: we compiled it [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>A while ago we wanted to choose a new natural language parser for our product. One of the strongest candidates in that area is the <a href="http://bllip.cs.brown.edu/resources.shtml">Charniak-Johnson</a> parser. We ended up not choosing to use this parser for various reasons, but in the process of evaluating it we produced a nice side benefit: we compiled it (well, the Charniak part of it) and ran it natively on Windows. </p>
<p>The source code for the converted project can be found on <a href="https://github.com/dorony/CharniakParserWindows">GitHub</a>, and the binaries can be found <a href="https://github.com/dorony/CharniakParserWindows/downloads">here</a>.</p>
<p>Now, before I tell you a bit about the conversion process, here are a few important notes:</p>
<ul>
<li>This is not the full CJ parser. This is the first-stage Charniak parser only (Aug06 version). The re-ranking second stage was not converted. </li>
<li>We converted only the non-multithreaded version of the main loop (oparseit.c and not parseit.c). Still, the parsing code should support calls from multiple threads should you choose to do so (up to the MAXNUMTHREADS parameter which defaults to 4). </li>
<li>This is a completely native version of the parser, it doesn’t need cygwin/mingw32 or anything of the sort. </li>
<li>It does need, however, the <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30679">Visual C++ 2012 Redistributables</a> to run. </li>
<li>You need Visual Studio 2012 to open the project (but you can probably easily port it to older VS versions). </li>
<li>We are not actually using this in our product, anywhere. We thought about using it, but we’re not. This is provided ‘as is’ as a service to the community, and the original license of the parser remains in place. </li>
</ul>
<p>So now that the formalities are out of the way, here are some details about the conversion process. First, I should note that I am no C++ expert. C# is my thing, and while I did some C/C++ projects in the university, it was quite a while ago. Therefore, it was not an easy task and it took me a few days to get the entire thing to work. Here are some things I had to do (probably not all, this was a long time ago):</p>
<ul>
<li>Convert all the .c files to .cpp files so Visual Studio will be happy with the code using C++ constructs. </li>
<li>Fix header issues of all sorts (like using #stdafx.h everywhere). </li>
<li>Add unicode support by changing all the constant strings to have the L macro applied on them, use wchar_t everywhere in the code, use wistream and friends instead of istream and friends, etc. </li>
<li>Figuring out code and files that are not needed for pure parsing and get rid of them. The less files I have to touch, the better. So for instance, I got rid of all the EvalTree stuff in the original parser (a different command which evaluates parse trees. Didn’t need that). </li>
</ul>
<p>The biggest headache, though, was the performance issue. For some reason, the parser performed much worse on Windows than on Linux, and it was pretty hard to understand why. I ended up using the Visual Studio C++ profiler, and traced the issue to a line that allocates a large array of objects. Digging a little further, I noticed that each allocated object contains a large std::list, so in fact, I was allocating lots of lists. The code basically boils down to this:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white">list&lt;<span style="color: #0000ff">char</span>*&gt;* item = <span style="color: #0000ff">new</span> list&lt;<span style="color: #0000ff">char</span>*&gt;[160000]; </pre>
<p><!--CRLF--></div>
</div>
<p>I measured the code above to be <em>10 times slower</em> on Windows than on Linux. Funky, eh? At first I thought that memory allocation on Windows is slower than on Linux. Who knows, right? Well, the folks at StackOverflow helped me <a href="http://stackoverflow.com/questions/9020475/windows-vs-linux-memory-allocation-stdlist-constructor-performance">realize</a> that memory allocation has nothing to do with this, it is actually the std::list constructor that is slower in the Microsoft implementation, probably because it allocates a bigger initial buffer. Once I knew this, I was able to tweak to code to dynamically allocate the std::lists, so I was able to create a lot less of them. This solved the performance issue, and in fact I measured the parser to be even <em>faster</em> on Windows that on Linux now.</p>
<p>That’s it for now, I guess. If you have any questions about using the binaries or the code posted above, please contact me. </p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2013/03/02/charniak-parser-on-windows/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Adapting Lucene scoring for an n-gram index</title>
		<link>http://blogs.microsoft.co.il/dorony/2012/10/24/adapting-lucene-scoring-for-an-n-gram-index/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2012/10/24/adapting-lucene-scoring-for-an-n-gram-index/#respond</comments>
		<pubDate>Wed, 24 Oct 2012 14:30:09 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
		
		<guid isPermaLink="false">http://blogs.microsoft.co.il/?p=1378031</guid>
		<description><![CDATA[At Ginger we use a large index of n-grams, which is basically a sequence of words and their frequency in our corpus. We wanted to make this index searchable, so naturally, we defaulted to using Lucene, which is the most popular open source IR library. This is how we started adding documents to the index: [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>At <a href="http://www.gingersoftware.com/">Ginger</a> we use a large index of <a href="http://en.wikipedia.org/wiki/N-gram">n-grams</a>, which is basically a sequence of words and their frequency in our corpus. We wanted to make this index searchable, so naturally, we defaulted to using <a href="http://lucene.apache.org/core/">Lucene</a>, which is the most popular open source IR library. This is how we started adding documents to the index:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> Document document = <span style="color: #0000ff">new</span> Document();</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> document.add(<span style="color: #0000ff">new</span> Field(<span style="color: #006080">&quot;ngram&quot;</span>, ngram, Field.Store.YES, Field.Index.ANALYZED));</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span> NumericField frequencyField = <span style="color: #0000ff">new</span> NumericField(<span style="color: #006080">&quot;frequency&quot;</span>, Field.Store.YES, true);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span> frequencyField.setLongValue(frequency);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum5" style="color: #606060">   5:</span> document.add(frequencyField);</pre>
<p><!--CRLF--></div>
</div>
<p>As you can see, we are indexing and storing both the <em>ngram</em> and the <em>frequency</em> fields, where one is a string and the other is a long.</p>
<p>After the indexing was done, we wanted to search the index. Our main use case for searching is this: take a bunch of words, and return <em>the most frequent</em> n-grams that contain them. My natural inclination was to use sorting for this, by using <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/search/IndexSearcher.html#search(org.apache.lucene.search.Query, int, org.apache.lucene.search.Sort)">IndexSearcher.search(Query query, int n, Sort sort)</a>. This allows us to supply a <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/search/Sort.html">Sort</a> object that would sort by the frequency field in descending order.</p>
<p>This turned out to be a bad idea. Lucene handles sorting by using the <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/search/FieldCache.html">FieldCache</a>. This means it tried to load <em>all the frequencies of all the n-grams in the index</em> into an array. This is a lot of data to load, and an OutOfMemoryException was thrown. But then I realized that I <em>always</em> wanted results to return ordered by frequency. I don’t need different result sets to be sorted by different fields, so this information should be stored in the index itself and shouldn’t require a cache. </p>
<p>Therefore, I arrived at the concept of <a href="http://lucene.apache.org/core/3_6_0/scoring.html">Scoring</a>. Scoring in Lucene determines how results are ordered by default, which is exactly what I needed. The default algorithm attempts to return the results most relevant to a given query, and I wanted to spice it up with my frequency information. The way you do that in Lucene is by using <a href="http://lucene.apache.org/core/3_6_0/scoring.html#Score Boosting">document level boosting</a>. This allows you to say that a specific document is more relevant than others. At first I did the naive thing and set the boost to be the frequency, like this:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> document.setBoost(frequency);</pre>
<p><!--CRLF--></div>
</p></div>
</div>
<p>It even seemed to work for a while, but then I noticed a couple of issues:</p>
<ol>
<li>The boost factor was too dominant: Lucene sometimes preferred to return n-grams with less query words, but have a greater frequency, over n-grams with more query words, but with less frequency. So, for instance if I search for “pleasure meet you” it would prefer “I want to meet you” (100000 frequency) over “pleasure to meet you” (10000 frequency). This caused me to revise my perspective: I don’t always want results to be returned ordered by frequency, the amount of contained query words is an important factor as well. </li>
<li>Sometimes results weren’t exactly ordered by frequency. An n-gram with 1000 frequency seemed to have exactly the same score as an n-gram with 10000 frequency, even though it was given a higher boost factor. </li>
</ol>
<p>While the first issue was rather obvious, the second one had me baffled for a while. It turns out even though the boost value is a <em>float</em>, it is stored as only a <em>byte</em>, as the document <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/search/Similarity.html#formula_norm">norm</a>. This value combines the document boost, the field boost (individual fields can be boosted as well, not useful for my case) and a length factor, which basically says that shorter documents are better (again not relevant for me, all the n-grams in a single index have the same length). So basically, we took a <em>long</em> (the frequency), which has a huge range of different values, and stuffed it into a <em>byte </em>which only allows for 256 different values. Obviously, I’m going to lose a bit of precision here. </p>
<p>The solution to both issues was to compute the boost in a different way. Instead of setting it to the frequency, we will set it to some function of the frequency. This should achieve:</p>
<ol>
<li>Smaller values for the boost factor, so it doesn’t override the coordination factor, which causes documents with more query terms to get a higher score. </li>
<li>A better ordering of n-grams by frequency. An n-gram with 2000 frequency should get a higher score than an n-gram with 1000 frequency, but I don’t care if an n-gram with 110000 frequency has the same score as 100000 frequency. In essence, I can afford losing precision at the higher ranges of frequency, but less so in the lower ranges. </li>
</ol>
<p>The function we came up with looks something like this:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">float</span> getBoost(<span style="color: #0000ff">long</span> frequency) {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>     <span style="color: #0000ff">double</span> boost = (Math.log(frequency) / Math.log(1.5)) * 10;</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">if</span> (boost &gt; 255)</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>         <span style="color: #0000ff">return</span> 255;</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>     <span style="color: #0000ff">return</span> Math.round((<span style="color: #0000ff">float</span>)boost);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>Basically, we want the boost to be a number between 1 and 255 (which achieves our first goal of smaller boost values). By taking a log of the frequency (base 1.5) we are not only getting smaller values, but also achieving our second goal, of better precision for lower frequency values.&#160; Above a certain threshold, all the n-grams will have the same boost factor of 255.</p>
<p>At this point I thought I was done, but I was still seeing precision loss. Lucene’s <a href="http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/api/core/org/apache/lucene/search/Similarity.html#encodeNormValue(float)">default way</a> of encoding a <em>float </em>to a <em>byte </em>and vice versa didn’t suit me; It tries to represent a large range of values when I just need to use 1-255. Therefore, I had to create my own Similarity class which overrides this behaviour.</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">class</span> NgramSimilarity <span style="color: #0000ff">extends</span> DefaultSimilarity { </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span>     @Override</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">float</span> computeNorm(String field, FieldInvertState state) {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum4" style="color: #606060">   4:</span>        <span style="color: #0000ff">return</span> state.getBoost();    <span style="color: #008000">//ignore length factor</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum5" style="color: #606060">   5:</span>    }     </pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum6" style="color: #606060">   6:</span>     @Override</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum7" style="color: #606060">   7:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">byte</span> encodeNormValue(<span style="color: #0000ff">float</span> f) {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum8" style="color: #606060">   8:</span>         <span style="color: #0000ff">return</span> (<span style="color: #0000ff">byte</span>)f;</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum9" style="color: #606060">   9:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum10" style="color: #606060">  10:</span>     @Override</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum11" style="color: #606060">  11:</span>     <span style="color: #0000ff">public</span> <span style="color: #0000ff">float</span> decodeNormValue(<span style="color: #0000ff">byte</span> b) {</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum12" style="color: #606060">  12:</span>         <span style="color: #0000ff">return</span> b &amp; 0xFF; <span style="color: #008000">//makes the byte unsigned so we can use the full 0-255 range</span></pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum13" style="color: #606060">  13:</span>     }</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum14" style="color: #606060">  14:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>First, since the length factor is irrelevant to us, we override <em>computeNorm </em>in order to ensure that norm = boost only. Second, as you can see, the encoding method is quite simple, and just casts the <em>float</em> to <em>byte</em>. We know for sure that the boost is in the range of 1-255 and that norm = boost, so we can safely cast. The decoding method is a little weirder; Apparently Java’s <em>byte</em> is signed (unlike C#’s <em>byte </em>which is unsigned). A simple cast back from <em>byte</em> to <em>float</em> would have a given us a negative number, hence we apply the 0xFF mask. </p>
<p>We now just have to apply our Similarity class to <a href="http://lucene.apache.org/core/3_6_0/api/all/org/apache/lucene/index/IndexWriter.html">IndexWriter</a>, like this:</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> IndexWriterConfig indexWriterConfig = <span style="color: #0000ff">new</span> IndexWriterConfig(Version.LUCENE_35, analyzer);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> indexWriterConfig.setSimilarity(<span style="color: #0000ff">new</span> NgramSimilarity());</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum3" style="color: #606060">   3:</span> IndexWriter writer = <span style="color: #0000ff">new</span> IndexWriter(directory, indexWriterConfig);</pre>
<p><!--CRLF--></div>
</div>
<p>It is also important to remember to use the custom Similarity class when searching (that’s when <em>decodeNormValue</em> is called):</p>
<div id="codeSnippetWrapper">
<div id="codeSnippet" style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4">
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: white"><span id="lnum1" style="color: #606060">   1:</span> IndexSearcher searcher = <span style="color: #0000ff">new</span> IndexSearcher(reader);</pre>
<p><!--CRLF--></p>
<pre style="border-top-style: none; overflow: visible; font-size: 8pt; border-left-style: none; font-family: &#39;Courier New&#39;, courier, monospace; border-bottom-style: none; color: black; padding-bottom: 0px; direction: ltr; text-align: left; padding-top: 0px; border-right-style: none; padding-left: 0px; margin: 0em; line-height: 12pt; padding-right: 0px; width: 100%; background-color: #f4f4f4"><span id="lnum2" style="color: #606060">   2:</span> searcher.setSimilarity(<span style="color: #0000ff">new</span> NgramSimilarity());</pre>
<p><!--CRLF--></div>
</div>
<p>And now we’re done.</p>
<p>My only niggle about Lucene is the documentation; It has excellent documentation, but only in the form of a <a href="http://www.manning.com/hatcher3/">book</a> (which I read and enjoyed). But a PDF book is a lot less cosy to work with than something that is truly online (like blog posts). You can’t google and get results from Lucene In Action. Other than that, I would say that Lucene has been a perfect fit for our purpose. It is easily customizable, so we could tune it to our specific needs, and gives excellent query performance.&#160; Open source is awesome, isn’t it?</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2012/10/24/adapting-lucene-scoring-for-an-n-gram-index/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Console.ReadKey .NET 4.5 changes may deadlock your system</title>
		<link>http://blogs.microsoft.co.il/dorony/2012/09/12/consolereadkey-net-45-changes-may-deadlock-your-system/</link>
		<comments>http://blogs.microsoft.co.il/dorony/2012/09/12/consolereadkey-net-45-changes-may-deadlock-your-system/#comments</comments>
		<pubDate>Wed, 12 Sep 2012 16:46:24 +0000</pubDate>
		<dc:creator><![CDATA[Doron Yaacoby]]></dc:creator>
				<category><![CDATA[.net]]></category>
		<category><![CDATA[.NET 4.5]]></category>
		<category><![CDATA[.NET Framework]]></category>
		<category><![CDATA[DEV]]></category>

		<guid isPermaLink="false">http://blogs.microsoft.co.il/?p=1279618</guid>
		<description><![CDATA[I’ve hit a weird issue today. We have a service that we run both as Windows service and from console. A specific use case seemed to cause our system to hang, but only when running from console. Also, I was sure this didn’t happen before I upgraded my machine to .NET 4.5. The service initialization [&#8230;]]]></description>
				<content:encoded><![CDATA[<p>I’ve hit a weird issue today. We have a service that we run both as Windows service and from console. A specific use case seemed to cause our system to hang, but only when running from console. Also, I was sure this didn’t happen before I upgraded my machine to .NET 4.5. The service initialization code looks something like this:</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">serviceHost.Open();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">&#160;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">while</span> (Console.ReadKey().Key != ConsoleKey.Q)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">{</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    Console.WriteLine(<span style="color: #006080">&quot;Press Q to exit&quot;</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">}</pre>
<p><!--CRLF--></div>
</div>
<p>Basically, we start a WCF service, and wait for the user to press Q to exit the application. Fairly standard, and used to work until .NET 4.5. </p>
<p>Digging a little further, I found out that the system was stuck on some third-party code which was doing something like:</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">Console.Error.WriteLine(<span style="color: #006080">&quot;Error!&quot;</span>);</pre>
<p><!--CRLF--></div>
</div>
<p>We have other places that write to stdout (Console.WriteLine), but this seems to be the only place that writes to stderr (and only in very specific cases, which is why I didn’t notice it until today). </p>
<p>In order to reproduce the issue, I wrote the following program:</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> Main()</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">{            </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    var readTask = <span style="color: #0000ff">new</span> Task(() =&gt;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">                                {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">                                    Console.WriteLine(<span style="color: #006080">&quot;enter something&quot;</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">                                    Console.ReadKey();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">                                });</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    var writeTask = <span style="color: #0000ff">new</span> Task(() =&gt; Console.Error.WriteLine(<span style="color: #006080">&quot;hello&quot;</span>));</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">&#160;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    readTask.Start();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    Thread.Sleep(100);            </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    writeTask.Start();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">&#160;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">    Task.WaitAll(readTask, writeTask);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px">}</pre>
<p><!--CRLF--></div>
</div>
<p>We have two threads, one waits for an input from the user, and the other writes to Console.Error. This program will never terminate under .NET 4.5 (at least until you press a key), but will terminate under .NET 4.0. Fun! Let’s compare the .NET 4.5 and 4.0 source code in order to find out what happens here. Here is Console.ReadKey in .NET 4.5:</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> Win32Native.InputRecord ir;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> <span style="color: #0000ff">int</span> numEventsRead = -1; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> <span style="color: #0000ff">bool</span> r;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> <span style="color: #0000ff">lock</span> (InternalSyncObject) {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>    <span style="color: #0000ff">if</span> (_cachedInputRecord.eventType == Win32Native.KEY_EVENT) { </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>        <span style="color: #008000">// We had a previous keystroke with repeated characters.</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>        ir = _cachedInputRecord; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>        <span style="color: #0000ff">if</span> (_cachedInputRecord.keyEvent.repeatCount == 0) </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span> ....</pre>
<p><!--CRLF--></div>
</div>
<p>Can you see the lock in line 5? It doesn’t exist in the .NET 4.0 source. And here’s Console.Error in both .NET 4.0 and 4.5:</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">public</span> <span style="color: #0000ff">static</span> TextWriter Error {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span>     [HostProtection(UI=<span style="color: #0000ff">true</span>)] </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     get { </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>         Contract.Ensures(Contract.Result&lt;TextWriter&gt;() != <span style="color: #0000ff">null</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #008000">// Hopefully this is inlineable. </span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>         <span style="color: #0000ff">if</span> (_error == <span style="color: #0000ff">null</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>             InitializeStdOutError(<span style="color: #0000ff">false</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>         <span style="color: #0000ff">return</span> _error;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span>     } </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum10">  10:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>As you can see, if this is the first time we’re using the stream it will try to initialize it. So let’s see the initialization code (again, for both .NET 4.0 and 4.5).</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> <span style="color: #0000ff">private</span> <span style="color: #0000ff">static</span> <span style="color: #0000ff">void</span> InitializeStdOutError(<span style="color: #0000ff">bool</span> stdout) </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span> { </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span>     <span style="color: #008000">// Set up Console.Out or Console.Error.</span></pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span>     <span style="color: #0000ff">lock</span>(InternalSyncObject) { </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span>         <span style="color: #0000ff">if</span> (stdout &amp;&amp; _out != <span style="color: #0000ff">null</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>             <span style="color: #0000ff">return</span>;</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span>         <span style="color: #0000ff">else</span> <span style="color: #0000ff">if</span> (!stdout &amp;&amp; _error != <span style="color: #0000ff">null</span>)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum8">   8:</span>             <span style="color: #0000ff">return</span>; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum9">   9:</span> ....</pre>
<p><!--CRLF--></div>
</div>
<p>Hmm, that lock seems familiar! This is what’s causing our code to deadlock. Console.ReadKey now locks a synchronization object which gets locked when you attempt to access stderr for the first time. Therefore, the solution is simple, we need to cause Console.Error to initialize <em>before </em>the call to Console.ReadKey.</p>
<div id="codeSnippetWrapper">
<div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet">
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum1">   1:</span> Console.Error.WriteLine(<span style="color: #006080">&quot;Initializing stderr to prevent threading issues...&quot;</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum2">   2:</span>&#160; </pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum3">   3:</span> serviceHost.Open();</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum4">   4:</span> <span style="color: #0000ff">while</span> (Console.ReadKey().Key != ConsoleKey.Q)</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum5">   5:</span> {</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum6">   6:</span>     Console.WriteLine(<span style="color: #006080">&quot;Press Q to exit&quot;</span>);</pre>
<p><!--CRLF--></p>
<pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &#39;Courier New&#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"><span style="color: #606060" id="lnum7">   7:</span> }</pre>
<p><!--CRLF--></div>
</div>
<p>Note that this may happen to you even if you’re targeting .NET 4.0, as long as you have .NET 4.5 installed. This is because .<a href="http://www.hanselman.com/blog/NETVersioningAndMultiTargetingNET45IsAnInplaceUpgradeToNET40.aspx">NET 4.5 is an in-place replacement for .NET 4.0,</a> so you’re always running with the safer (and deadlock-causing) Console.ReadKey() if you installed the new framework version.</p>
]]></content:encoded>
			<wfw:commentRss>http://blogs.microsoft.co.il/dorony/2012/09/12/consolereadkey-net-45-changes-may-deadlock-your-system/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
