<?xml version="1.0" encoding="utf-8"?><rss version="2.0"><channel><title>Li Chen's Blog</title><link>https://weblogs.asp.net:443/lichen/</link><description></description><item><title>Porting a C# Windows application to Linux</title><link>https://weblogs.asp.net:443/lichen/porting-a-c-windows-application-to-linux</link><description>&lt;p&gt;I own a Windows application. To expand our customer base, we need to create a Linux edition. In anticipating the demand, we previously decided to place the majority of logics in a few .net standard libraries and this is a big paid-off. However, there are still a few things we need to do so that the same code would work on both Windows and Linux.&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Path separator is different between Windows and Linux. Windows uses “\” as separator while Linux uses “/” as separator. The solution is to always use Path.Combine to concatenate paths. Similarly, use Path.GetDirectoryName and Path.GetFileName to split the paths.&lt;/li&gt;&lt;li&gt;Linux file system is case sensitive. The solution is to be very consistent with path names and always use constants when a path is used in multiple places.&lt;/li&gt;&lt;li&gt;In text files, Windows uses \r\n to end lines while Linux uses \r. The solution is to use TextReader.ReadLine and TextWriter.WriteLine. TextReader.ReadLine reads Windows text files correctly on Linux and vice versa. If we have to face line-ending characters explicitly, use Environment.NewLine.&lt;/li&gt;&lt;li&gt;Different locations for program files and program data. Windows by defaults store programs in “c:\Program Files” folder and store program data in “c:\ProgramData”. The exact location can be determined from the %ProgramFile% and %ProgramData% environment variables. Linux, in contrast, has a different convention and one often install programs under /opt and write program data under /var. For complete reference, see: &lt;a title="http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/" href="http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/"&gt;http://www.tldp.org/LDP/Linux-Filesystem-Hierarchy/html/&lt;/a&gt;. This is an area we have to branch the code and detect operating system using RuntimeInformation.IsOSPlatform.&lt;/li&gt;&lt;li&gt;Lack of registry in Linux. The solution is to just use configuration files.&lt;/li&gt;&lt;li&gt;Windows has services while Linux has daemon. The solution is to create a Windows Service application on Windows and create a console application on Linux. RedHat has a good article on creating Linux daemon in C#: &lt;a title="https://developers.redhat.com/blog/2017/06/07/writing-a-linux-daemon-in-c/" href="https://developers.redhat.com/blog/2017/06/07/writing-a-linux-daemon-in-c/"&gt;https://developers.redhat.com/blog/2017/06/07/writing-a-linux-daemon-in-c/&lt;/a&gt;. For addition information on Systemd, also see: &lt;a title="https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files" href="https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files"&gt;https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Packaging and distribution. Windows application are usually packaged as msi or Chocolatey package. Linux applications are usually packaged as rpm. This will be the subject of another blog post.&lt;/li&gt;&lt;/ol&gt;</description><pubDate>Sun, 12 Aug 2018 21:02:51 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/porting-a-c-windows-application-to-linux</guid><category>.net</category><category>.net core</category><category>Linux</category></item><item><title>Building .net core on an unsupported Linux platform</title><link>https://weblogs.asp.net:443/lichen/building-net-core-on-an-unsupported-linux-platform</link><description>&lt;h1&gt;Introduction&lt;/h1&gt;
&lt;p&gt;I need to a product that I own from Windows to Amazon Linux. However, Amazon Linux is not a supported platform for running .net core by Microsoft. Although there is a Amazon Linux 2 image with .net core 2.1 preinstalled and it is possible to install the CentOS version of .net core on Amazon Linux 1, I went on a journey to build and test .net core on Amazon Linux to have confidence that my product will not hit a wall.&lt;/p&gt;
&lt;p&gt;.net core require LLVM 3.9 to build. However, we can only get LLVM 3.6.3 from the yum repository. So we have to build LLVM 3.9.LLVM 3.9 requires Cmake 3.11 or later, but we can only get Cmake 2.8.12 from the yum repository. So we have to start from building CMake.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;h1&gt;Building CMake&lt;/h1&gt;
&lt;p&gt;The procedure to build CMake can be found in &lt;a title="https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line
" href="https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line."&gt;https://askubuntu.com/questions/355565/how-do-i-install-the-latest-version-of-cmake-from-the-command-line.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here is what I did:&lt;/p&gt;
&lt;p&gt;sudo yum groupinstall "Development Tools"&lt;/p&gt;
&lt;p&gt;Sudo yum install swig python27-devel libedit-devel&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;version=3.11&lt;br /&gt; build=1&lt;br /&gt; mkdir ~/temp&lt;br /&gt; cd ~/temp&lt;br /&gt; wget &lt;a href="https://cmake.org/files/v"&gt;https://cmake.org/files/v&lt;/a&gt;$version/cmake-$version.$build.tar.gz&lt;br /&gt; tar -xzvf cmake-$version.$build.tar.gz&lt;br /&gt; cd cmake-$version.$build/&lt;/p&gt;
&lt;p&gt;./bootstrap&lt;/p&gt;
&lt;p&gt;make -j4&lt;br /&gt; sudo make install&lt;/p&gt;
&lt;h1&gt;Building CLang and LVVM&lt;/h1&gt;
&lt;p&gt;With CMake installed, we can build LLVM. My procedure of building Clang and LLVM is similar to the procedure in &lt;a title="https://github.com/dotnet/coreclr/blob/master/Documentation/building/buildinglldb.md
" href="https://github.com/dotnet/coreclr/blob/master/Documentation/building/buildinglldb.md. "&gt;https://github.com/dotnet/coreclr/blob/master/Documentation/building/buildinglldb.md. &lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Please also refer to &lt;a href="https://releases.llvm.org/3.9.1/docs/CMake.html"&gt;https://releases.llvm.org/3.9.1/docs/CMake.html&lt;/a&gt; for additional information.&lt;/p&gt;
&lt;p&gt;cd $HOME&lt;br /&gt; git clone &lt;a href="http://llvm.org/git/llvm.git"&gt;http://llvm.org/git/llvm.git&lt;/a&gt;&lt;br /&gt; cd $HOME/llvm&lt;br /&gt; git checkout release_39&lt;br /&gt; cd $HOME/llvm/tools&lt;br /&gt; git clone &lt;a href="http://llvm.org/git/clang.git"&gt;http://llvm.org/git/clang.git&lt;/a&gt; &lt;br /&gt; git clone &lt;a href="http://llvm.org/git/lldb.git"&gt;http://llvm.org/git/lldb.git&lt;/a&gt; &lt;br /&gt; cd $HOME/llvm/tools/clang&lt;br /&gt; git checkout release_39&lt;br /&gt; cd $HOME/llvm/tools/lldb&lt;br /&gt; git checkout release_39&lt;/p&gt;
&lt;p&gt;Before we start building, we need to patch LLVM source code for Amazon Linux triplet.Otherwise LLVM cannot find the c++ compiler on Amazon Linux.&lt;/p&gt;
&lt;p&gt;To patch, find file ./tools/clang/lib/Driver/ToolChains.cpp, find an array that looks like:&lt;/p&gt;
&lt;p&gt;"x86_64-linux-gnu", "x86_64-unknown-linux-gnu", "x86_64-pc-linux-gnu",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "x86_64-redhat-linux6E", "x86_64-redhat-linux", "x86_64-suse-linux",&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "x86_64-manbo-linux-gnu", "x86_64-linux-gnu", "x86_64-slackware-linux", &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; "x86_64-linux-android", "x86_64-unknown-linux"&lt;/p&gt;
&lt;p&gt;Append "x86_64-amazon-linux" to the last line.&lt;/p&gt;
&lt;p&gt;Similar, append "i686-amazon-linux" to "i686-montavista-linux", "i686-linux-android", "i586-linux-gnu"&lt;/p&gt;
&lt;p&gt;Now we can build:&lt;/p&gt;
&lt;p&gt;mkdir -p $HOME/build/release&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br /&gt; cd $HOME/build/release&lt;br /&gt; cmake -DCMAKE_BUILD_TYPE=release $HOME/llvm&lt;/p&gt;
&lt;p&gt;make &amp;ndash;j4&lt;/p&gt;
&lt;p&gt;sudo make install&lt;/p&gt;
&lt;h1&gt;Building CoreCLR and CoreFx&lt;/h1&gt;
&lt;p&gt;With Clang/LLVM 3.9 installed, we can now build CoreCLR and CoreFx.&lt;/p&gt;
&lt;p&gt;&lt;br /&gt; &lt;a href="https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md"&gt;https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;We need to install the prerequisites first:&lt;/p&gt;
&lt;p&gt;sudo yum install lttng-ust-devel libunwind-devel gettext libicu-devel libcurl-devel openssl-devel krb5-devel libuuid-devel libcxx&lt;/p&gt;
&lt;p&gt;sudo yum install redhat-lsb-core cppcheck sloccount&lt;/p&gt;
&lt;p&gt;mkdir ~/git&lt;/p&gt;
&lt;p&gt;git clone &lt;a href="https://github.com/dotnet/coreclr.git"&gt;https://github.com/dotnet/coreclr.git&lt;/a&gt;&lt;br /&gt; git clone &lt;a href="https://github.com/dotnet/corefx.git"&gt;https://github.com/dotnet/corefx.git&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Go to each directory and check out a version, for eample:&lt;/p&gt;
&lt;p&gt;git checkout tags/v2.0.7&lt;/p&gt;
&lt;p&gt;Now just follow &lt;a href="https://github.com/dotnet/coreclr/blob/master/Documentation/building/linux-instructions.md"&gt;https://github.com/dotnet/coreclr/blob/master/Documentation/building/linux-instructions.md&lt;/a&gt; to the build.&lt;/p&gt;
&lt;p&gt;./clean.sh -all&lt;br /&gt; ./build.sh -RuntimeOS=linux&lt;br /&gt; ./build-tests.sh&lt;/p&gt;
&lt;p&gt;Also look at: &lt;a title="https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md" href="https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md"&gt;https://github.com/dotnet/corefx/blob/master/Documentation/project-docs/developer-guide.md&lt;/a&gt; and&lt;/p&gt;
&lt;p&gt;&lt;a title="https://github.com/dotnet/corefx/issues/22509" href="https://github.com/dotnet/corefx/issues/22509"&gt;https://github.com/dotnet/corefx/issues/22509&lt;/a&gt;&lt;/p&gt;
&lt;h1&gt;Conclusions&lt;/h1&gt;
&lt;p&gt;With the steps above, I was able to build and test .net core on Amazon Linux 1 and 2.&lt;/p&gt;
&lt;p&gt;Note that .net core requires GLIBC_2.14 to run. To find the version of GLIBC on your version of Amazon Linux, run:&lt;/p&gt;
&lt;p&gt;strings /lib64/libc.so.6 | grep GLIBC&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t see 2.14 on the list, .net core will not run. try &amp;ldquo;sudo yum update&amp;rdquo; to see if you can update to a later version of GLIBC.&lt;/p&gt;
&lt;p&gt;Additionally, since many newer programming languages were build on LLVM, this exercise also allow us to build other languages that require newer version of LLVM than the version in the yum repository.&lt;/p&gt;</description><pubDate>Sun, 12 Aug 2018 06:11:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/building-net-core-on-an-unsupported-linux-platform</guid><category>.NET</category><category>.net core</category><category>Linux</category><category>Amazon Linux</category></item><item><title>Configure Open Live Writer to weblogs.asp.net</title><link>https://weblogs.asp.net:443/lichen/configure-open-live-writer-to-weblogs-asp-net</link><description>&lt;p&gt;I have not blogged for a while. When I opened my Open Live Writer, I got error with &lt;a href="https://weblogs.asp.net/lichen/xmlrpc"&gt;https://weblogs.asp.net/lichen/xmlrpc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;I searched the web. Most blogs were still referencing the xmlrpc url which no longer exists.&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;Fortunately, Fixing is easy. Just Add Account and select &amp;ldquo;Other services&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aspblogs.blob.core.windows.net/media/lichen/Open-Live-Writer/Configure-Open-Live-Writer-to-Weblog.net_10084/livewriter1_1.png"&gt;&lt;img width="244" height="209" title="livewriter1" style="display: inline; background-image: none;" alt="livewriter1" src="https://aspblogs.blob.core.windows.net/media/lichen/Open-Live-Writer/Configure-Open-Live-Writer-to-Weblog.net_10084/livewriter1_thumb_1.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;p&gt;On the next screen, enter the url of the blog (without xmlrpc).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aspblogs.blob.core.windows.net/media/lichen/Open-Live-Writer/Configure-Open-Live-Writer-to-Weblog.net_10084/livewriter2.png"&gt;&lt;img width="244" height="206" title="livewriter2" style="display: inline; background-image: none;" alt="livewriter2" src="https://aspblogs.blob.core.windows.net/media/lichen/Open-Live-Writer/Configure-Open-Live-Writer-to-Weblog.net_10084/livewriter2_thumb.png" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Open Live Writer and Orchard are smart enough to figure out the rest. This is certainly an improvement over the earlier versions.&lt;/p&gt;
&lt;p&gt;If you are curious on how Open Live Writer figured out the post API endpoint, which view the source of your web page and you will see the following lines in the header:&lt;/p&gt;
&lt;p&gt;&amp;lt;link href="&lt;a href="https://weblogs.asp.net/lichen/XmlRpc/LiveWriter/Manifest&amp;quot;"&gt;https://weblogs.asp.net/lichen/XmlRpc/LiveWriter/Manifest"&lt;/a&gt; rel="wlwmanifest" type="application/wlwmanifest+xml" /&amp;gt;&lt;br /&gt; &amp;lt;link href="&lt;a href="https://weblogs.asp.net/lichen/rsd&amp;quot;"&gt;https://weblogs.asp.net/lichen/rsd"&lt;/a&gt; rel="EditURI" title="RSD" type="application/rsd+xml" /&amp;gt;&lt;/p&gt;</description><pubDate>Sun, 12 Aug 2018 01:32:27 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/configure-open-live-writer-to-weblogs-asp-net</guid><category>orchard</category><category>open live writer</category></item><item><title>Top k algorithm revisited</title><link>https://weblogs.asp.net:443/lichen/top-k-algorithm-revisited</link><description>&lt;p&gt;3 years ago, I implemented &lt;a href="https://weblogs.asp.net/lichen/an-efficient-top-k-algorithm-with-implementation-in-c-for-linq"&gt;top K operator in LINQ&lt;/a&gt;. I was asked recently why I chose Min Heap since there are faster algorithms. To recap, we try to select top k element from a sequence of n elements. A min-heap has the following property:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;find-min takes O(1) time.&lt;/li&gt;&lt;li&gt;extract-min takes O(ln k) time where k is the size of the heap.&lt;/li&gt;&lt;li&gt;insert takes O(ln k) time.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For each number in the sequence, I first compare the number to find-min. If the number is smaller, the number is tossed away. If the number is bigger, we do a extract-min followed by an insert. So in the worst scenario, the algorithm runs with time complexity of O(n ln k) and the space complexity of O(k).&lt;/p&gt;&lt;p&gt;If we use max-heap instead, we can heapify n elements in O(n) time. Then we do k extract-max so we have the total time complexity of O(n + k ln n) and a space complexity of O(n).&lt;/p&gt;&lt;p&gt;We could also use Quick Select. It is very similar to Quick Sort that we randomly select a pivot and move it to the right position. Unlike Quick Sort, we can discard the left side of the pivot whenever we have greater then k elements on the right side. This algorithm converge fairly quickly and we have the average time complexity of O(n) and space complexity of O(n). In average case, the space requirement by Quick Select is less than the max heap approach.&lt;/p&gt;&lt;p&gt;So both max-heap and quick select are likely faster than the min-heap approach. Why do I used min-heap then? The reason is that the min-heap approach uses minimum amount of memory and I assume that I will work with large dataset so . Also, if we work with a stream, the min-heap provides a running top k.&lt;/p&gt;</description><pubDate>Wed, 08 Mar 2017 07:08:23 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/top-k-algorithm-revisited</guid></item><item><title>Ever wonder on which platform Amazon AWS Lambda in C# is running?</title><link>https://weblogs.asp.net:443/lichen/ever-wonder-on-which-platform-amazon-aws-lambda-in-c-is-running</link><description>&lt;p&gt;In last December, AWS &lt;a href="https://aws.amazon.com/about-aws/whats-new/2016/12/aws-lambda-supports-c-sharp/"&gt;announced&lt;/a&gt; C# support for AWS Lambda using .NET Core 1.0 runtime. Ever wonder on which platform is it running? I am curious too and I did not see it in any official documentation. So I decided to write a small AWS Lambda function to detect the platform:&lt;/p&gt;
&lt;p&gt;&lt;/p&gt;
&lt;pre style="font-family: Consolas; font-size: 13; color: black; background: white;"&gt;&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;System;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;System.Collections.Generic;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;System.Linq;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;System.Threading.Tasks;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;System.Runtime.InteropServices;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;Amazon.Lambda.Core;
&lt;span style="color: blue;"&gt;using&lt;/span&gt;&amp;nbsp;Amazon.Lambda.Serialization;
 
&lt;span style="color: green;"&gt;//&amp;nbsp;Assembly&amp;nbsp;attribute&amp;nbsp;to&amp;nbsp;enable&amp;nbsp;the&amp;nbsp;Lambda&amp;nbsp;function's&amp;nbsp;JSON&amp;nbsp;input&amp;nbsp;to&amp;nbsp;be&amp;nbsp;converted&amp;nbsp;into&amp;nbsp;a&amp;nbsp;.NET&amp;nbsp;class.&lt;/span&gt;
[&lt;span style="color: blue;"&gt;assembly&lt;/span&gt;:&amp;nbsp;&lt;span style="color: #2b91af;"&gt;LambdaSerializer&lt;/span&gt;&lt;span style="color: #2b91af;"&gt;Attribute&lt;/span&gt;(&lt;span style="color: blue;"&gt;typeof&lt;/span&gt;(Amazon.Lambda.Serialization.Json.&lt;span style="color: #2b91af;"&gt;JsonSerializer&lt;/span&gt;))]
 
&lt;span style="color: blue;"&gt;namespace&lt;/span&gt;&amp;nbsp;SysInfoLambda
{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Function&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: gray;"&gt;summary&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;A&amp;nbsp;simple&amp;nbsp;function&amp;nbsp;that&amp;nbsp;takes&amp;nbsp;a&amp;nbsp;string&amp;nbsp;and&amp;nbsp;does&amp;nbsp;a&amp;nbsp;ToUpper&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: gray;"&gt;summary&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: gray;"&gt;param&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;nbsp;name&lt;/span&gt;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&lt;span style="color: gray;"&gt;"&lt;/span&gt;input&lt;span style="color: gray;"&gt;"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: gray;"&gt;param&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: gray;"&gt;param&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;nbsp;name&lt;/span&gt;&lt;span style="color: gray;"&gt;=&lt;/span&gt;&lt;span style="color: gray;"&gt;"&lt;/span&gt;context&lt;span style="color: gray;"&gt;"&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: gray;"&gt;param&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: gray;"&gt;///&lt;/span&gt;&lt;span style="color: green;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: gray;"&gt;returns&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: gray;"&gt;returns&lt;/span&gt;&lt;span style="color: gray;"&gt;&amp;gt;&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInfo&lt;/span&gt;&amp;nbsp;FunctionHandler(&lt;span style="color: #2b91af;"&gt;ILambdaContext&lt;/span&gt;&amp;nbsp;context)
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;return&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInfo&lt;/span&gt;()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;FrameworkDescription&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.FrameworkDescription,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OSArchitecture&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.OSArchitecture,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;ProcessArchitecture&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.ProcessArchitecture,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OSDescription&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.OSDescription,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OSPlatform&amp;nbsp;=&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.IsOSPlatform(&lt;span style="color: #2b91af;"&gt;OSPlatform&lt;/span&gt;.Linux)&amp;nbsp;?&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OS&lt;/span&gt;.Linux&amp;nbsp;:
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInformation&lt;/span&gt;.IsOSPlatform(&lt;span style="color: #2b91af;"&gt;OSPlatform&lt;/span&gt;.OSX)&amp;nbsp;?&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OS&lt;/span&gt;.OSX&amp;nbsp;:&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OS&lt;/span&gt;.Windows
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;};
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;class&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;RuntimeInfo&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;nbsp;FrameworkDescription&amp;nbsp;{&amp;nbsp;&lt;span style="color: blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color: blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Architecture&lt;/span&gt;&amp;nbsp;OSArchitecture&amp;nbsp;{&amp;nbsp;&lt;span style="color: blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color: blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;string&lt;/span&gt;&amp;nbsp;OSDescription&amp;nbsp;{&amp;nbsp;&lt;span style="color: blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color: blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;Architecture&lt;/span&gt;&amp;nbsp;ProcessArchitecture&amp;nbsp;{&amp;nbsp;&lt;span style="color: blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color: blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OS&lt;/span&gt;&amp;nbsp;OSPlatform&amp;nbsp;{&amp;nbsp;&lt;span style="color: blue;"&gt;get&lt;/span&gt;;&amp;nbsp;&lt;span style="color: blue;"&gt;set&lt;/span&gt;;&amp;nbsp;}
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
 
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="color: blue;"&gt;enum&lt;/span&gt;&amp;nbsp;&lt;span style="color: #2b91af;"&gt;OS&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Linux,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;OSX,
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Windows
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}
 
}
&lt;/pre&gt;
&lt;p&gt;The result? The AWS C# Lambda runs in 64 bit Linux. The extract OS description is: Linux 4.4.35-33.55.amzn1.x86_64 #1 SMP Tue Dec 6 20:30:04 UTC 2016.&lt;/p&gt;</description><pubDate>Tue, 14 Feb 2017 07:17:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/ever-wonder-on-which-platform-amazon-aws-lambda-in-c-is-running</guid><category>c#</category><category>AWS</category><category>.net core</category></item><item><title>NSession is quietly marching towards 1.0 release</title><link>https://weblogs.asp.net:443/lichen/nsession-is-quietly-marching-towards-1-0-release</link><description>&lt;p&gt;My open source project &lt;a href="https://nsession.codeplex.com/"&gt;NSession&lt;/a&gt; has be around for several years. It allows ASP classic pages to access ASP.NET out-of-process session states the same way that ASP.NET pages access them. Recently, there are a large number of users migrating from Windows 2003 to Windows Server 2008/2012 and encountered an incompatibility with ASP.NET 4.5. I was contacted by users daily publicly or privately. I decided to make additional effort to put finishing touch on it to make it a 1.0 product.&lt;/p&gt; &lt;p&gt;In 0.9.0.1 release, I had:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Fixed the compatibility issues with asp.net 4.5.&lt;/li&gt; &lt;li&gt;Improved the documents.&lt;/li&gt; &lt;li&gt;Reduced hacking to make it less likely to encounter compatibility problem with future versions of ASP.NET.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;In 0.9.1.2 release, I had:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;Added support for SQL Server session state so that it supports all the built-in out-of-proc session states in ASP.NET and is feature complete for 1.0 release.&lt;/li&gt; &lt;li&gt;Added a &lt;a href="https://nsession.codeplex.com/wikipage?title=Trouble%20Shooting&amp;amp;referringTitle=Documentation"&gt;diagnostic check list&lt;/a&gt; and a &lt;a href="https://nsession.codeplex.com/SourceControl/latest#NSessionTest/NSessionDiagnotics.aspx"&gt;diagnostic tool&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;Before 1.0 release, I will continue improving installation experience, fixing bugs reported and will do some performance testing.&lt;/p&gt; &lt;p&gt;Beyond 1.0, I will start designing adapter interface to support custom session states. Please visit the &lt;a href="https://nsession.codeplex.com/"&gt;project site&lt;/a&gt; to propose custom session state providers to support in &lt;a href="https://nsession.codeplex.com/workitem/list/basic"&gt;the work items area&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Sun, 12 Apr 2015 21:21:29 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/nsession-is-quietly-marching-towards-1-0-release</guid><category>ASP.NET</category><category>NSession</category><category>ASP Classic</category></item><item><title>First look at the Visual Studio Tools for Apache Cordova CTP 3.1</title><link>https://weblogs.asp.net:443/lichen/first-look-at-the-visual-studio-tools-for-apache-cordova-ctp-3-1</link><description>&lt;p&gt;The company that I worked for had an old cross-platform mobile app developed by an outside contractor using PhoneGap 1.0. When I was asked to look at the app a few months ago, I had great difficulty collecting large number of moving pieces: PhoneGap, Android SDK and emulator. When I saw &lt;a href="https://msdn.microsoft.com/en-us/library/dn771545.aspx"&gt;Visual Studio Tools for Apache Cordova&lt;/a&gt; (I will call it VSTAC in the remaining of this post), I decide to give it a try since it attempts to install a large number of third-party software for me.&lt;/p&gt;  &lt;p&gt;The journey is not exactly easy, but it is certainly far easier than collecting all the pieces myself with &lt;a href="https://msdn.microsoft.com/en-us/library/dn757054.aspx"&gt;the excellent installation document from MSDN&lt;/a&gt;. The result is more than pleasant. Here are some of my findings:&lt;/p&gt;  &lt;p&gt;1) After the installation, I could not even get a hello world app to work. It turns out that I had an older version of Nods.js. VSTAC skipped node.js installation. After I uninstall the old node.js and reinstall with the one linked from the VSTAC installation page, I was able to get hello world to work.&lt;/p&gt;  &lt;p&gt;2) I was surprise to see the Ripple emulator which I was not aware of previously. The Ripple emulator is very fast and VSTAC provides excellent debugging experience.&lt;/p&gt;  &lt;p&gt;3) I had to clear my Apache Cordova cache a few times. This and some other useful items are documented in &lt;a href="https://www.visualstudio.com/explore/cordova-faq-vs"&gt;FAQ&lt;/a&gt;. Also visit &lt;a href="https://www.visualstudio.com/explore/cordova-known-issues-vs"&gt;known issues&lt;/a&gt;.&lt;/p&gt;  &lt;p&gt;4) The application connects to an old soap web services developed with WCF. It does not support CORS. So I had to use Ripple proxy to connect to it but I kept getting 400 error. Fortunately, I was able to &lt;a href="http://stackoverflow.com/questions/29222701/400-error-calling-wcf-web-service-from-ripple-emulator/29244798#29244798"&gt;hack Ripple proxy&lt;/a&gt; to make it work.&lt;/p&gt;  &lt;p&gt;5) I then tried to run the app in Google Android emulator. VSTAC supports this scenario as well. I had to uninstall and reinstall some Android SDK components following &lt;a href="https://msdn.microsoft.com/en-us/library/dn757054.aspx#ThirdParty"&gt;this&lt;/a&gt; and &lt;a href="https://msdn.microsoft.com/en-us/library/dn757059.aspx"&gt;this&lt;/a&gt; directions. Then I had to run AVD Manager to &lt;a href="https://msdn.microsoft.com/en-us/library/dn757059.aspx"&gt;create and start a device&lt;/a&gt;. Then I had to update my display driver to make sure I have compatible OpenGL ES driver installed. After that, the Google emulator ran beautifully. It was not as fast as Ripple but is acceptable.&lt;/p&gt;  &lt;p&gt;So at the end, I want to give a big thank you to the Microsoft VSTAC team. I know this is not easy but the excellent document got me through. It certainly saved me lots of time.&lt;/p&gt;</description><pubDate>Wed, 25 Mar 2015 23:17:19 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/first-look-at-the-visual-studio-tools-for-apache-cordova-ctp-3-1</guid></item><item><title>Missing methods in LINQ: MaxWithIndex and MinWithIndex</title><link>https://weblogs.asp.net:443/lichen/missing-methods-in-linq-maxwithindex-and-minwithindex</link><description>&lt;p&gt;The LINQ library has &lt;a href="http://msdn.microsoft.com/en-us/library/vstudio/system.linq.enumerable.max(v=vs.100).aspx"&gt;Max methods&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/vstudio/system.linq.enumerable.min(v=vs.100).aspx"&gt;Min methods&lt;/a&gt;. However, sometimes we are interested in the index location in the IEnumerable&amp;lt;T&amp;gt; rather than the actual values. Hence the MaxWithIndex and MinWithIndex methods.&lt;/p&gt; &lt;p&gt;These methods return a Tuple. The first item of the Tuple is the maximum or minimum value just the the Max and Min methods. The second item of the Tuple is the index location.&lt;/p&gt; &lt;p&gt;As usually, you might get my LINQ extension from NuGet:&lt;/p&gt; &lt;p&gt;PM&amp;gt;Install-Package SkyLinq.Linq&lt;/p&gt; &lt;p&gt;Usage examples in the &lt;a href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Linq.Test/LinqExtTest.cs"&gt;unit test&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Sun, 05 Oct 2014 22:50:01 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/missing-methods-in-linq-maxwithindex-and-minwithindex</guid><category>LINQ</category><category>C#</category><category>.NET</category></item><item><title>ASP Classic Compiler is now available in NuGet</title><link>https://weblogs.asp.net:443/lichen/asp-classic-compiler-is-now-available-in-nuget</link><description>&lt;p&gt;I know this is very, very late, but I hope it is better than never. To make it easy to experiment with &lt;a href="http://aspclassiccompiler.codeplex.com/"&gt;ASP Classic Compiler&lt;/a&gt;, I made the .net 4.x binaries available in &lt;a href="https://www.nuget.org/packages/Dlrsoft.Asp/"&gt;NuGet&lt;/a&gt;. So it is now extremely easy to try it:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;From the package console of any .NET 4.x web project, run &amp;ldquo;Install-Package Dlrsoft.Asp&amp;rdquo;.&lt;/li&gt;
&lt;li&gt;To switch from AspClassic to Asp Classic Compiler in the project, add the following section to the system.webServer handlers section:
&lt;pre style="font-family: consolas; background: white; color: black;"&gt;&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.webServer&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;handlers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;remove&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ASPClassic&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515;"&gt;add&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;name&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;ASPClassic&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;verb&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;*&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;path&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;*.asp&lt;/span&gt;"&lt;span style="color: blue;"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red;"&gt;type&lt;/span&gt;&lt;span style="color: blue;"&gt;=&lt;/span&gt;"&lt;span style="color: blue;"&gt;Dlrsoft.Asp.AspHandler, Dlrsoft.Asp&lt;/span&gt;"&lt;span style="color: blue;"&gt;/&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;handlers&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue;"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515;"&gt;system.webServer&lt;/span&gt;&lt;span style="color: blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
Comment out the section to switch back.&lt;/li&gt;
&lt;li&gt;&lt;span style="font-family: Courier New;" face="Courier New"&gt;Add a test page StringBuilder.asp:&lt;/span&gt;
&lt;pre style="font-family: Consolas; font-size: 13; color: black; background: white;"&gt;&lt;span style="background: yellow;"&gt;&amp;lt;%&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;imports&amp;nbsp;system
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;dim&lt;/span&gt;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;&lt;span style="color: blue;"&gt;new&lt;/span&gt;&amp;nbsp;system.text.stringbuilder()
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;dim&lt;/span&gt;&amp;nbsp;i
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;table&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;for&lt;/span&gt;&amp;nbsp;i&amp;nbsp;=&amp;nbsp;1&amp;nbsp;&lt;span style="color: blue;"&gt;to&lt;/span&gt;&amp;nbsp;12
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;tr&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;td&amp;gt;"&lt;/span&gt;&amp;nbsp;+&amp;nbsp;i&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;/td&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;td&amp;gt;"&lt;/span&gt;&amp;nbsp;+&amp;nbsp;MonthName(i)&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;/td&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;/tr&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="color: blue;"&gt;next&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;s&amp;nbsp;=&amp;nbsp;s&amp;nbsp;+&amp;nbsp;&lt;span style="color: maroon;"&gt;"&amp;lt;/table&amp;gt;"&lt;/span&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;response.Write(s)
 
&lt;span style="background: yellow;"&gt;%&amp;gt;&lt;/span&gt;&lt;/pre&gt;
This code uses the .net extension so it will only work with Asp Classic Compiler.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Happy experimenting!&lt;/p&gt;</description><pubDate>Sun, 28 Sep 2014 19:06:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/asp-classic-compiler-is-now-available-in-nuget</guid><category>ASP Classic Compiler</category><category>ASP.NET</category></item><item><title>SkyLinq binaries are available on NuGet</title><link>https://weblogs.asp.net:443/lichen/skylinq-binaries-are-available-on-nuget</link><description>&lt;p&gt;After much hesitate, I finally published my &lt;a href="https://www.nuget.org/packages?q=skylinq"&gt;SkyLinq binaries&lt;/a&gt; on NuGet. My main hesitation was that this is my playground so I am changing things at will. The main reason to publish is that I want to use these works myself so I need an easy way to get the latest binaries into my projects. NuGet is the easiest way to distribute and get updates, including my own projects. There are 3 packages:&lt;/p&gt; &lt;ul&gt; &lt;li&gt;SkyLinq.Linq is a portal library that contains &lt;a href="https://weblogs.asp.net/lichen/Tags/LINQ"&gt;some LINQ extensions&lt;/a&gt;. &lt;/li&gt; &lt;li&gt;SkyLinq.Composition contains &lt;a href="https://weblogs.asp.net/lichen/a-c-implementation-of-duck-typing"&gt;my duck-typing implementation&lt;/a&gt;. It is similar to Impromptu-Interface but it is much simpler and it uses il.emit instead of LINQ Expressions to generate code. It also contains a &lt;a href="https://weblogs.asp.net/lichen/linq-query-optimization-by-query-rewriting-using-a-custom-iqueryable-linq-provider"&gt;LINQ query rewriting example&lt;/a&gt;.&lt;/li&gt; &lt;li&gt;LINQPadHost is &lt;a href="https://weblogs.asp.net/lichen/a-simple-linqpad-query-host"&gt;a simple hosting and executing environment for LINQPad queries&lt;/a&gt;. Live demo at &lt;a title="http://skylinq.azurewebsites.net/SkyLINQPad" href="http://skylinq.azurewebsites.net/SkyLINQPad"&gt;http://skylinq.azurewebsites.net/SkyLINQPad&lt;/a&gt;.&lt;/li&gt;&lt;/ul&gt;</description><pubDate>Sat, 13 Sep 2014 20:30:39 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/skylinq-binaries-are-available-on-nuget</guid><category>C#</category><category>LINQ</category></item><item><title>Sky LINQPad, a minimum viable clone of LINQPad in the cloud</title><link>https://weblogs.asp.net:443/lichen/sky-linqpad-a-minimum-viable-clone-of-linqpad-in-the-cloud</link><description>&lt;p&gt;A while ago, I blogged about &lt;a href="https://weblogs.asp.net/lichen/a-simple-linqpad-query-host"&gt;a simple LINQPad query host&lt;/a&gt;. It is fairly easy to put a web face on it. The only change that I had to make is to set the ApplicationBase for the AppDomains that I create as asp.net is quite different to an .exe app. A playground is now running at &lt;a title="http://skylinq.azurewebsites.net/SkyLINQPad" href="http://skylinq.azurewebsites.net/SkyLINQPad"&gt;http://skylinq.azurewebsites.net/SkyLINQPad&lt;/a&gt;. One can upload an existing .linq files designed in LINQPad or type some queries directly into the page:&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;img title="image" style="background-image: none; padding-top: 0px; padding-left: 0px; margin: 0px; display: inline; padding-right: 0px; border: 0px;" alt="image" src="https://aspblogs.blob.core.windows.net/media/lichen/Windows-Live-Writer/Sky_A8FE/image_2.png" border="0" /&gt;&lt;/p&gt;</description><pubDate>Sat, 13 Sep 2014 20:09:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/sky-linqpad-a-minimum-viable-clone-of-linqpad-in-the-cloud</guid><category>LINQ</category><category>ASP.NET</category><category>C#</category></item><item><title>A simple LINQPad query host</title><link>https://weblogs.asp.net:443/lichen/a-simple-linqpad-query-host</link><description>&lt;p&gt;I am a big fan of &lt;a href="http://www.linqpad.net/"&gt;LINQPad&lt;/a&gt;. I use LINQPad routinely during my work to test small, incremental ideas. I used it so much so that I bough myself a &lt;a href="http://www.linqpad.net/Purchase.aspx"&gt;premium license&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;I always wish I can run queries designed in LINQPad in my own program. Before 4.52.1 beta, there was only a command line interface. In &lt;a href="http://www.linqpad.net/Beta.aspx"&gt;LINQPad v4.52.1 beta&lt;/a&gt;, there is finally a Util.Run method that allows me to run LINQPad queries in my own process. However, I felt that I did not have sufficient control on how I can dump the results. So I decided to write a simple host myself.&lt;/p&gt; &lt;p&gt;As in the example below, a .linq file starts with an xml meta data section followed by a blank line and then the query or the statements.&lt;/p&gt;&lt;pre style="font-family: consolas; background: white; color: black"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Query&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="color: red"&gt;Kind&lt;/span&gt;&lt;span style="color: blue"&gt;=&lt;/span&gt;"&lt;span style="color: blue"&gt;Expression&lt;/span&gt;"&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Reference&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;lt;&lt;/span&gt;RuntimeDirectory&lt;span style="color: red"&gt;&amp;amp;gt;&lt;/span&gt;\System.Web.dll&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Reference&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Reference&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color: red"&gt;&amp;amp;lt;&lt;/span&gt;ProgramFilesX86&lt;span style="color: red"&gt;&amp;amp;gt;&lt;/span&gt;\Microsoft ASP.NET\ASP.NET MVC 4\Assemblies\System.Web.Mvc.dll&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Reference&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;System.Web&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;System.Web.Mvc&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Namespace&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;Query&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;
 
HttpUtility.UrlEncode("\"'a,b;c.d'\"")&lt;/pre&gt;
&lt;p&gt;The article “&lt;a title="http://www.linqpad.net/HowLINQPadWorks.aspx" href="http://www.linqpad.net/HowLINQPadWorks.aspx"&gt;http://www.linqpad.net/HowLINQPadWorks.aspx&lt;/a&gt;” on the LINQPad website gives me good information on how to compile and execute queries.&amp;nbsp; LINQPad uses CSharpCodeProvider (or VBCodeProvider) to compile queries. Although I was tempted to use &lt;a href="http://msdn.microsoft.com/en-us/vstudio/roslyn.aspx"&gt;Roslyn&lt;/a&gt; like &lt;a href="http://scriptcs.net/"&gt;ScriptCS&lt;/a&gt;, I decided to use CSharpCodeProvider to ensure compatible with LINQPad.&lt;/p&gt;
&lt;p&gt;We only need 3 lines of code to the LINQPad host:&lt;/p&gt;&lt;pre&gt;using LINQPadHost;
...
string file = @"C:\Users\lichen\Documents\LINQPad Queries\ServerUtility.linq";
Host host = new Host();
host.Run&amp;lt;JsonTextSerializer&amp;gt;&lt;jsontextserializer&gt;(file);
&lt;/pre&gt;
&lt;p&gt;As I mentioned at the beginning. I would like to control the dumping of the results. JsonTextSerializer is one of the three serializers that I supplied. The other two serializers are IndentTextSerializer and XmlTextSerializer. Personally, I found that the JsonTextSerializer and IndentTextSerializer the most useful.&lt;/p&gt;
&lt;p&gt;The source code could be found &lt;a href="http://skylinq.codeplex.com/SourceControl/latest"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Examples could be found &lt;a href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Example/LINQPadHostExample.cs"&gt;here&lt;/a&gt;.&lt;/p&gt;</description><pubDate>Tue, 02 Sep 2014 04:00:45 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/a-simple-linqpad-query-host</guid><category>LINQ</category><category>C#</category><category>.NET</category></item><item><title>Why every .net developer should learn some PowerShell</title><link>https://weblogs.asp.net:443/lichen/why-every-net-developer-should-learn-some-powershell</link><description>&lt;p&gt;It has been 8 years since PowerShell v.1 was shipped in 2006. I have looked into PowerShell closely except for using it in the &lt;a href="http://docs.nuget.org/docs/start-here/Using-the-Package-Manager-Console"&gt;Nuget Console&lt;/a&gt;. Recently, I was forced to have a much closer look at PowerShell because we use a product that exposes its only interface in PowerShell.&lt;/p&gt; &lt;p&gt;Then I realized that PowerShell is such a wonderful product that every .net developer should learn some. Here are some reasons:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;PowerShell is a much better language that the DOS batch language. PowerShell is &lt;a href="http://technet.microsoft.com/en-us/magazine/hh551144.aspx"&gt;real language&lt;/a&gt; with variable, condition, looping and function calls.  &lt;li&gt;According to Douglas Finke in &lt;a href="http://www.amazon.com/gp/product/1449322700/ref=as_li_tl?ie=UTF8&amp;amp;camp=1789&amp;amp;creative=9325&amp;amp;creativeASIN=1449322700&amp;amp;linkCode=as2&amp;amp;tag=wwwdotneteeco-20&amp;amp;linkId=R2VUUE3C2PXBKMVM&amp;quot;&amp;gt;Windows PowerShell for Developers&amp;lt;/a&amp;gt;&amp;lt;img src=&amp;quot;http://ir-na.amazon-adsystem.com/e/ir?t=wwwdotneteeco-20&amp;amp;l=as2&amp;amp;o=1&amp;amp;a=1449322700"&gt;Windows Powershell for Developers&lt;/a&gt; by O’Reilly, PowerShell is a stop ship event, meaning no Microsoft server products ship without a PowerShell interface.  &lt;li&gt;PowerShell now has a pretty good &lt;a href="http://technet.microsoft.com/en-us/library/dd819514.aspx"&gt;Integrated Scripting Environments&lt;/a&gt; (ISE). We can create, edit, run and debug PowerShell. Microsoft has release &lt;a href="http://blogs.technet.com/b/onescript/archive/2014/04/16/releasing-script-browser-for-windows-powershell-ise.aspx"&gt;OneScript&lt;/a&gt;, a script browser and analyzer that could be run from PowerShell ISE.  &lt;li&gt;We can call &lt;a href="http://technet.microsoft.com/en-us/library/dd347709.aspx"&gt;.NET and COM objects from PowerShell&lt;/a&gt;. That is an advantage over VBScript.  &lt;li&gt;PowerShell has a wonderful &lt;a href="http://technet.microsoft.com/en-us/library/ee176927.aspx"&gt;pipeline model&lt;/a&gt; with which we can filter, sort and convert results. If you love &lt;a href="https://weblogs.asp.net/lichen/Tags/LINQ"&gt;LINQ&lt;/a&gt;, you would love PowerShell.  &lt;li&gt;It is possible to &lt;a href="http://blogs.msdn.com/b/skaufman/archive/2010/03/31/calling-powershell-from-net.aspx"&gt;call PowerShell script from .net&lt;/a&gt;, even ones on a &lt;a href="http://msdn.microsoft.com/en-us/library/ee706560%28VS.85%29.aspx"&gt;remote machine&lt;/a&gt;.&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;Recently, I have to call some PowerShell scripts on a remote server. There are many piecewise information on the internet, but no many good examples. So I put a few pointers here:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;When connecting to remote PowerShell, the uri is : &lt;a href="http://SERVERNAME:5985/wsman"&gt;http://SERVERNAME:5985/wsman&lt;/a&gt;.  &lt;li&gt;It is possible to run PowerShell in a different credential using the optional credential.  &lt;li&gt;Powershell remoting only runs in PowerShell 2.0 or later. So download the PowerShell 2.0 SDK (&lt;a title="http://www.microsoft.com/en-us/download/details.aspx?id=2560" href="http://www.microsoft.com/en-us/download/details.aspx?id=2560"&gt;http://www.microsoft.com/en-us/download/details.aspx?id=2560&lt;/a&gt;). When installed, it actually updates the 1.0 reference assemblies . On my machine, they are in: C:\Program Files (x86)\Reference Assemblies\Microsoft\WindowsPowerShell\v1.0&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;So the complete code runs like:&lt;/p&gt;&lt;pre&gt;using System.Management.Automation; // Windows PowerShell namespace
using System.Management.Automation.Runspaces; // Windows PowerShell namespace
using System.Security; // For the secure password
using Microsoft.PowerShell;

	    Runspace remoteRunspace = null;
            //System.Security.SecureString password = new System.Security.SecureString();
            //foreach (char c in livePass.ToCharArray())
            //{
            //    password.AppendChar(c);
            //}
            //PSCredential psc = new PSCredential(username, password);
            //WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(uri), schema, psc);
            WSManConnectionInfo rri = new WSManConnectionInfo(new Uri(""http://SERVERNAME:5985/wsman"));
            //rri.AuthenticationMechanism = AuthenticationMechanism.Kerberos;
            //rri.ProxyAuthentication = AuthenticationMechanism.Negotiate;
            remoteRunspace = RunspaceFactory.CreateRunspace(rri);
            remoteRunspace.Open();

	    using (PowerShell powershell = PowerShell.Create())
                {
                    powershell.Runspace = remoteRunspace;
                    powershell.AddCommand(scriptText);
                    Collection&lt;psobject&gt; results = powershell.Invoke();
                    remoteRunspace.Close();
                    foreach (PSObject obj in results)
                    {
                        foreach (PSPropertyInfo psPropertyInfo in obj.Properties)
                        {
                            Console.Write("name: " + psPropertyInfo.Name);
                            Console.Write("\tvalue: " + psPropertyInfo.Value);
                            Console.WriteLine("\tmemberType: " + psPropertyInfo.MemberType);
                        }
                    }
                }

&lt;/pre&gt;</description><pubDate>Sun, 17 Aug 2014 18:30:24 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/why-every-net-developer-should-learn-some-powershell</guid><category>.NET</category><category>C#</category><category>PowerShell</category></item><item><title>Implement a simple priority queue</title><link>https://weblogs.asp.net:443/lichen/implement-a-simple-priority-queue</link><description>&lt;p&gt;.NET framework does not have a priority queue built-in. There are several open source &lt;a href="http://stackoverflow.com/questions/102398/priority-queue-in-net"&gt;implementations&lt;/a&gt;. If you do not want to reference an entire library, it is fairly easy to implement one yourself. Many priority queue implementations &lt;a href="http://en.wikipedia.org/wiki/Priority_queue"&gt;use heap&lt;/a&gt;. However, if the number of levels of priorities is small, it is actually very easy and efficient to implement priority queues using an array of queues. There is a &lt;a href="http://msdn.microsoft.com/en-us/library/7977ey2c(v=vs.110).aspx"&gt;queue implementation&lt;/a&gt; in the .net framework.&lt;/p&gt; &lt;p&gt;My implementation is in the code below. The enum QueuePriorityEnum contains the number of levels of priorities. It is picked up automatically by the PriorityQueue class. The queue support 3 operations: Enqueue, Dequeue and Count. There behavior is modeled after the Queue class in the .net framework.&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;pre&gt;using System;
using System.Collections.Generic;
using System.Linq;

namespace MyNamespace
{
    // Modify this enum to add number of levels. It will picked up automatically
    enum QueuePriorityEnum
    {
        Low = 0,
        High =1
    }

    class PriorityQueue&amp;lt;T&amp;gt;&lt;t&gt;
    {
        Queue&amp;lt;T&amp;gt;&lt;t&gt;[] _queues;

        public PriorityQueue()
        {
            int levels = Enum.GetValues(typeof(QueuePriorityEnum)).Length;
            _queues = new Queue&amp;lt;T&amp;gt;&lt;t&gt;[levels];
            for (int i = 0; i &amp;lt; levels; i++)
            {
                _queues[i] = new Queue&amp;lt;T&amp;gt;&lt;t&gt;();
            }
        }

        public void Enqueue(QueuePriorityEnum priority, T item)
        {
	    _queues[(int)priority].Enqueue(item);
        }

        public int Count
        {
            get
            {
                return _queues.Sum(q =&amp;gt; q.Count);
            }
        }

        public T Dequeue()
        {
	    int levels = Enum.GetValues(typeof(QueuePriorityEnum)).Length;
	    for (int i = levels - 1; i &amp;gt; -1; i--)
	    {
		if (_queues[i].Count &amp;gt; 0)
		{
			return _queues[i].Dequeue();
		}
	    }
            throw new InvalidOperationException("The Queue is empty. ");
        }
    }
}

&lt;/pre&gt;</description><pubDate>Sun, 27 Jul 2014 03:24:02 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/implement-a-simple-priority-queue</guid><category>C#</category></item><item><title>integrating external systems with TFS</title><link>https://weblogs.asp.net:443/lichen/integrating-external-systems-with-tfs</link><description>&lt;p&gt;Recently, we need to integrate external systems with TFS. TFS is a feature-rich system and has a &lt;a href="http://msdn.microsoft.com/en-us/library/bb130146.aspx"&gt;large API&lt;/a&gt;. The &lt;a href="http://msdn.microsoft.com/en-us/library/bb286958.aspx"&gt;TFS sample on MSDN&lt;/a&gt; only scratch the top surface. Fortunately, a couple of good blog posts get me on the write direction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://blogs.msdn.com/b/buckh/archive/2012/03/10/team-foundation-version-control-client-api-example-for-tfs-2010-and-newer.aspx"&gt;Team Foundation Version Control client API example for TFS 2010 and newer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://paulselles.wordpress.com/2014/01/08/team-foundation-server-api-programmatically-downloading-files-from-source-control/"&gt;Team Foundation Server API: Programmatically Downloading Files From Source Control&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key is to use the VersionControlService. We need to reference the following assemblies:&lt;/p&gt;
&lt;p&gt;Microsoft.TeamFoundation.Client.dll&lt;/p&gt;
&lt;p&gt;Microsoft.TeamFoundation.Common.dll&lt;/p&gt;
&lt;p&gt;Microsoft.TeamFoundation.VersionControl.Client.dll&lt;/p&gt;
&lt;p&gt;Microsoft.TeamFoundation.VersionControl.Common.dll&lt;/p&gt;
&lt;p&gt;The code would be something like:&lt;/p&gt;
&lt;pre&gt;using Microsoft.TeamFoundation.Client;
using Microsoft.TeamFoundation.Framework.Common;
using Microsoft.TeamFoundation.Framework.Client;
using Microsoft.TeamFoundation.VersionControl.Client;

...

TfsTeamProjectCollection pc = TfsTeamProjectCollectionFactory.GetTeamProjectCollection(tfsUri);
VersionControlServer vcs = pc.GetService&lt;versioncontrolserver&gt;();
&lt;/versioncontrolserver&gt;&lt;/pre&gt;
&lt;p&gt;Then to check whether a file exists, we can use:&lt;/p&gt;
&lt;pre&gt;vcs.ServerItemExists(myPath, ItemType.File)&lt;/pre&gt;
&lt;p&gt;Or check if a directory exists:&lt;/p&gt;
&lt;pre&gt;vcs.ServerItemExists(myPath, ItemType.Folder)&lt;/pre&gt;
&lt;p&gt;To get a list of directories or files, we can use the GetItems method. TFS is far more complicated than a file system. We can get a file, get the history of a file, get a changeset, etc. Therefore, the GetItems method has many overloads. To get a list files, we can use:&lt;/p&gt;
&lt;pre&gt;var fileSet = vcs.GetItems(myPath, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.NonDeleted, ItemType.File);
foreach (Item f in fileSet.Items)
{
    Console.WriteLine(f.ServerItem);
}&lt;/pre&gt;
&lt;p&gt;Or get a list of directories:&lt;/p&gt;
&lt;pre&gt;var dirSet = vcs.GetItems(myPath, VersionSpec.Latest, RecursionType.OneLevel, DeletedState.NonDeleted, ItemType.Folder);
foreach (Item d in dirSet.Items)
{
    Console.WriteLine(d.ServerItem);
}&lt;/pre&gt;</description><pubDate>Sat, 19 Jul 2014 04:56:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/integrating-external-systems-with-tfs</guid><category>C#</category><category>TFS</category><category>Visual Studio</category></item><item><title>Converted ASP Classic Compiler project from Mercurial to Git</title><link>https://weblogs.asp.net:443/lichen/converted-asp-classic-compiler-project-from-mercurial-to-git</link><description>&lt;p&gt;Like &lt;a href="http://blog.tatham.oddie.com.au/2014/03/24/nerd-corner-convert-a-mercurial-hg-repo-to-git-with-full-fidelity-on-any-os/"&gt;some other&lt;/a&gt; open source project developers, I picked the Mercurial as my version control system. Unfortunately, Git is winning in the Visual Studio echo systems. Fortunately, it is possible to contact Codeplex admin for manual conversion from Mercurial to Git. I have done exactly that for my &lt;a href="https://aspclassiccompiler.codeplex.com/"&gt;open source ASP Classic Compiler project&lt;/a&gt;. Now I can add new examples in response to forum questions and check them in using my Visual Studio 2013. Now I am all happy.&lt;/p&gt;</description><pubDate>Sun, 30 Mar 2014 19:09:29 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/converted-asp-classic-compiler-project-from-mercurial-to-git</guid><category>.NET</category><category>ASP Classic Compiler</category><category>ASP.NET</category></item><item><title>Video review: RESTful Services with ASP.NET Web API from PACKT Publishing</title><link>https://weblogs.asp.net:443/lichen/video-review-restful-services-with-asp-net-web-api-from-packt-publishing</link><description>&lt;p&gt;&lt;em&gt;Disclaimer: I was provided this video for free by PACKT Publishing. However, that does not affect my opinion about this video.&lt;/em&gt;&lt;/p&gt;  &lt;p&gt;Upon request by PACKT Publishing, I agreed to watch and review the video “&lt;a href="http://www.packtpub.com/restful-services-with-aspnet-web-api/video"&gt;RESTful Service with ASP.NET Web API&lt;/a&gt;” by Fanie Reynders. Prior to the review, I have a EBook called “&lt;a href="http://shop.oreilly.com/product/0636920026617.do"&gt;Designing Evolvable Web APIs with ASP.NET - Harnessing the power of the web&lt;/a&gt;” by Glenn Block, Pablo Cibraro, Pedro Felix, Howard Dierking and Darrel Miller from O’Reilly. I also have access to several videos on the &lt;a href="http://www.pluralsight.com/training/Courses/Find?highlight=true&amp;amp;searchTerm=web+api"&gt;Pluralsight.com&lt;/a&gt; on the same subject. So I would put my review in perspective with those other materials.&lt;/p&gt;  &lt;p&gt;The video from Packt has the length of 2 hours 4 minutes. It gave a nice overview over the ASP.NET Web API. The video is available for watch online or for downloading to watch offline. The video has 8 chapters. It covers the ASP.NET Web API in a clear and accurate way and is surprisingly complete for this short length.&lt;/p&gt;  &lt;p&gt;In comparison with other resources, I would recommend you get this video if you have never worked with ASP.NET Web API before and want to get a complete overview in a short time possible.&lt;/p&gt;  &lt;p&gt;If you love video, Pluralsight is offering the equally good and slightly longer (3h 15m)&amp;#160; “&lt;a href="http://pluralsight.com/training/courses/TableOfContents?courseName=aspnetwebapi&amp;amp;highlight=jon-flanders_aspnetwebapi-m1-introduction!jon-flanders_aspnetwebapi-m5-security*0!jon-flanders_aspnetwebapi-m4-hosting*0#aspnetwebapi-m1-introduction"&gt;Introduction to the ASP.NET Web API&lt;/a&gt;” by Jon Flanders. You would need subscription to access the exercise materials thought. If you do subscribe, Pluralsight also has a couple of intermediate level videos by Shawn Wildermuth.&lt;/p&gt;  &lt;p&gt;Lastly, if you want an in depth book that you can use for a extended period of time, it is hard to beat Glenn Block, etc.’s book from O’Reilly.&lt;/p&gt;</description><pubDate>Sat, 22 Mar 2014 20:49:17 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/video-review-restful-services-with-asp-net-web-api-from-packt-publishing</guid><category>ASP.NET</category><category>ASP.NET Web API</category></item><item><title>LINQ query optimization by query rewriting using a custom IQueryable LINQ provider</title><link>https://weblogs.asp.net:443/lichen/linq-query-optimization-by-query-rewriting-using-a-custom-iqueryable-linq-provider</link><description>&lt;p&gt;In my &lt;a href="https://skylinq.codeplex.com/" mce_href="https://skylinq.codeplex.com/"&gt;SkyLinq&lt;/a&gt; open source project so far, I tried to make LINQ better and created several extension methods (for example, see &lt;a href="http://weblogs.asp.net/lichen/archive/2013/12/14/be-aware-of-the-memory-implication-of-groupby-in-linq.aspx" mce_href="http://weblogs.asp.net/lichen/archive/2013/12/14/be-aware-of-the-memory-implication-of-groupby-in-linq.aspx"&gt;GroupBy&lt;/a&gt; and &lt;a href="http://weblogs.asp.net/lichen/archive/2014/01/15/an-efficient-top-k-algorithm-with-implementation-in-c-for-linq.aspx" mce_href="http://weblogs.asp.net/lichen/archive/2014/01/15/an-efficient-top-k-algorithm-with-implementation-in-c-for-linq.aspx"&gt;TopK&lt;/a&gt;) that are more memory efficient than the standard methods in some scenarios. However, I do not necessarily want people to bind into these extensions methods directly for the following reasons:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Good ideas evolve. New methods may come and existing methods may change.&lt;/li&gt;
&lt;li&gt;There is a parallel set of methods in IEnumerable&amp;lt;T&amp;gt;, IQueryable&amp;lt;T&amp;gt; and to some degree, in IObservable&amp;lt;T&amp;gt;. Using custom LINQ extension breaks the parallelism.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;A better approach would be to write the LINQ queries normally using the standard library methods and then optimize the queries using a custom query provider. Query rewriting is not a new idea. SQL server has been doing this for years. I would like to bring this idea into LINQ.&lt;/p&gt;
&lt;p&gt;If we examine the IQueryable&amp;lt;T&amp;gt; interface, we will find there is a parallel set of LINQ methods that accepts Expression&amp;lt;Func&amp;gt; instead of &amp;lt;Func&amp;gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_7A056B97.png" mce_href="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_7A056B97.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_7A056B97.png" border="0" mce_src="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_7A056B97.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;There is a little C# compiler trick here. If C# see a method that accepts Expression&amp;lt;Func&amp;gt;, it would create Expressions of Lamda instead of compiled Lambda expression. At run time, these expressions are passed to an IQueryable implementation and then passed to the underlying IQueryProvider implementation. The query provider is responsible for executing the expression tree and return the results. This is how the magic of LINQ to SQL and Entity Frameworks works.&lt;/p&gt;
&lt;p&gt;The .net framework already has a class called &lt;a href="http://msdn.microsoft.com/en-us/library/cc190116(v=vs.110).aspx" mce_href="http://msdn.microsoft.com/en-us/library/cc190116(v=vs.110).aspx"&gt;EnumerableQuery&amp;lt;T&amp;gt;&lt;/a&gt;. It is a query provider than turns IQueryable class into LINQ to objects queries. In this work, I am going one step further by creating an optimizing query provider.&lt;/p&gt;
&lt;p&gt;A common perception of writing a custom LINQ provider is that it requires &lt;a href="https://www.re-motion.org/blogs/mix/2009/09/02/how-to-write-a-linq-provider-the-simple-way" mce_href="https://www.re-motion.org/blogs/mix/2009/09/02/how-to-write-a-linq-provider-the-simple-way"&gt;a lot of code&lt;/a&gt;. The reason is that even for the most trivial provider we need to visit the every possible expressions in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions(v=vs.90).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.linq.expressions(v=vs.90).aspx"&gt;System.Linq.Expressions&lt;/a&gt; namespace. (Note that we only need to handle expressions as of .net framework 3.5 but do not need to handle the new expressions added as part of dynamic language runtime in .net 4.x). There are reusable framework such as &lt;a href="http://iqtoolkit.codeplex.com/" mce_href="http://iqtoolkit.codeplex.com/"&gt;IQToolkit project&lt;/a&gt; that makes it easier to create a custom LINQ provider.&lt;/p&gt;
&lt;p&gt;In contrast, creating an optimizing query provider is fairly easy. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor(v=vs.110).aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.linq.expressions.expressionvisitor(v=vs.110).aspx"&gt;ExpressionVistor&lt;/a&gt; class already has the framework that I need. I only needed to create a subclass of ExpressionVisitor called &lt;a href="https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Composition/SkyLinqRewriter.cs" mce_href="https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Composition/SkyLinqRewriter.cs"&gt;SkyLinqRewriter&lt;/a&gt; to override a few methods. The query rewriter basically replaces all call to the Queryable class with equivalent calls to the Enumerable class and rewrite queries for optimization when an opportunity presents.&lt;/p&gt;
&lt;p&gt;It is fairly easy to consume the optimizing query provider. All we need is to call AsSkyLinqQueryable() to convert IEnumerable&amp;lt;T&amp;gt; to IQueryable&amp;lt;T&amp;gt; and remaining code can stay intact:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_4D7C3BB1.png" mce_href="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_4D7C3BB1.png"&gt;&lt;img title="image" style="border-width: 0px; display: inline;" alt="image" src="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_4D7C3BB1.png" border="0" mce_src="https://aspblogs.blob.core.windows.net/media/lichen/Media/image_4D7C3BB1.png" /&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;An end-to-end example can be found at &lt;a title="https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Example/LinqToW3SVCLogExample.cs" href="https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Example/LinqToW3SVCLogExample.cs" mce_href="https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Example/LinqToW3SVCLogExample.cs"&gt;https://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Example/LinqToW3SVCLogExample.cs&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;To conclude this post, I would recommend that we always code to IQueryable&amp;lt;T&amp;gt; instead of IEnumerable&amp;lt;T&amp;gt;. This way, the code has the flexibility to be optimized by an optimizing query provider, or be converted from pull based query to push based query using &lt;a href="https://rx.codeplex.com/" mce_href="https://rx.codeplex.com/"&gt;Reactive Extension&lt;/a&gt; without rewriting any code.&lt;/p&gt;</description><pubDate>Fri, 14 Feb 2014 04:23:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/linq-query-optimization-by-query-rewriting-using-a-custom-iqueryable-linq-provider</guid><category>.NET</category><category>C#</category><category>LINQ</category></item><item><title>Expression tree visualizer for Visual Studio 2013</title><link>https://weblogs.asp.net:443/lichen/expression-tree-visualizer-for-visual-studio-2013</link><description>&lt;p&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/bb397975(v=vs.90).aspx"&gt;Expression tree visualizer&lt;/a&gt;, as the name indicates, is a Visual Studio visualizer for visualizing expression trees. It is a must if you work with expressions frequently. Expression Tree Visualizer is a &lt;a href="http://code.msdn.microsoft.com/vstudio/ExpressionTreeVisualizer-3dbdf0c7"&gt;Visual Studio 2008 sample&lt;/a&gt;. There is a &lt;a href="http://exprtreevisualizer.codeplex.com/"&gt;Visual Studio 2010 port&lt;/a&gt; available on codeplex. If you want to use it with a later version of Visual Studio, there is not one available. Fortunately, porting it to another version of Visual Studio is fairly simple:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Download the original source code from &lt;a title="http://exprtreevisualizer.codeplex.com/" href="http://exprtreevisualizer.codeplex.com/"&gt;http://exprtreevisualizer.codeplex.com/&lt;/a&gt;.&lt;/li&gt;    &lt;li&gt;Replace the existing reference to Microsoft.VisualStudio.DebuggerVisualizers assembly to the version in the Visual Studio you want to work with. For Visual Studio 2013, I found it in C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\ReferenceAssemblies\v2.0\Microsoft.VisualStudio.DebuggerVisualizers.dll on my computer.&lt;/li&gt;    &lt;li&gt;Compile the ExpressionTreeVisualizer project and copy ExpressionTreeVisualizer.dll to the visualizer directory. To make it usable by one user, just copy it to My Documents\VisualStudioVersion\Visualizers. To make it usable by all users of a machine, copy it to VisualStudioInstallPath\Common7\Packages\Debugger\Visualizers.&lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;If you do not want to walk through the process, I have one readily available at &lt;a title="http://weblogs.asp.net/blogs/lichen/ExpressionTreeVisualizer.Vs2013.zip" href="https://aspblogs.blob.core.windows.net/media/lichen/Media/ExpressionTreeVisualizer.Vs2013.zip"&gt;http://weblogs.asp.net/blogs/lichen/ExpressionTreeVisualizer.Vs2013.zip&lt;/a&gt;. Just do not sue me if it does not work as expected.&lt;/p&gt;</description><pubDate>Mon, 10 Feb 2014 00:27:02 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/expression-tree-visualizer-for-visual-studio-2013</guid><category>.NET</category><category>C#</category></item><item><title>An efficient Top K algorithm with implementation in C# for LINQ</title><link>https://weblogs.asp.net:443/lichen/an-efficient-top-k-algorithm-with-implementation-in-c-for-linq</link><description>
&lt;p&gt;The LINQ library currently does not have a dedicated top K implementation. Programs usually use &lt;a href="http://technet.microsoft.com/en-us/library/ee391229.aspx" mce_href="http://technet.microsoft.com/en-us/library/ee391229.aspx"&gt;the OrderBy function followed by the Take function&lt;/a&gt;. For N items, an efficient sort algorithm would scale O(n) in space and O(n log n) in time. Since we are counting the top K, I believe that we could devise an algorithm that scales O(K) in space.&lt;/p&gt;
  
&lt;p&gt;Among all the sorting algorithms that I am familiar, the &lt;a href="http://en.wikipedia.org/wiki/Heapsort" mce_href="http://en.wikipedia.org/wiki/Heapsort"&gt;heapsort&lt;/a&gt; algorithm came to my mind first. A &lt;a href="http://en.wikipedia.org/wiki/Heap_(data_structure)" mce_href="http://en.wikipedia.org/wiki/Heap_(data_structure)"&gt;Heap&lt;/a&gt; has a tree-like data structure that can often be implemented using an array. A heap can either be a max-heap or a min-heap. In the case of min-heap, the minimum element of at the root of the tree and all the child elements are greater than their parents.&lt;/p&gt;
  
&lt;p&gt;&lt;a href="http://en.wikipedia.org/wiki/Binary_heap" mce_href="http://en.wikipedia.org/wiki/Binary_heap"&gt;Binary heap&lt;/a&gt; is a special case of heap. A binary min-heap has the following characteristics:&lt;/p&gt;
  
&lt;ul&gt;   
&lt;li&gt;find-min takes O(1) time.&lt;/li&gt;
    
&lt;li&gt;delete-min takes O(log n) time.&lt;/li&gt;
    
&lt;li&gt;insert takes O(log n) time.&lt;/li&gt;
 &lt;/ul&gt;
  
&lt;p&gt;So here is how I implement my top K algorithm:&lt;/p&gt;
  
&lt;ol&gt;   
&lt;li&gt;Create a heap with an array of size K.&lt;/li&gt;
    
&lt;li&gt;Insert items into the heap until the heap reaches its capacity. This takes K O(log K) time.&lt;/li&gt;
    
&lt;li&gt;For each the remaining elements, if an element is greater than find-min of the heap, do a delete-min and then insert the element into the heap. &lt;/li&gt;
    
&lt;li&gt;Then we repeated delete-min until the heap is empty and arrange the deleted element in reverse order and we get our top 10 list.&lt;/li&gt;
 &lt;/ol&gt;
  
&lt;p&gt;The time it takes to find top K items from an N item list is:&lt;/p&gt;
  
&lt;p&gt;O(N) * t1 + O((K + log N - log K) * log K) * t2&lt;/p&gt;
  
&lt;p&gt;Here t1 is the time to compare an element in step 3 to find-min and t2 is the combined time of delete-min and the subsequent insert. So this algorithm is much more efficient that a call to OrderBy followed by a call to Take.&lt;/p&gt;
  
&lt;p&gt;I have checked-in my implementation to my &lt;a href="http://skylinq.codeplex.com/" mce_href="http://skylinq.codeplex.com/"&gt;Sky LINQ project&lt;/a&gt;. The LINQ Top and Bottom is at in &lt;a href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Linq/LinqExt.cs" mce_href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Linq/LinqExt.cs"&gt;LinqExt.cs&lt;/a&gt;. The internal binary heap implementation is in &lt;a href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Linq/Algorithms/BinaryHeap.cs" mce_href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Linq/Algorithms/BinaryHeap.cs"&gt;BinaryHeap.cs&lt;/a&gt;. The LINQ example can be found in &lt;a href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Sample/HeapSort.cs" mce_href="http://skylinq.codeplex.com/SourceControl/latest#SkyLinq.Sample/HeapSort.cs"&gt;HeapSort.cs&lt;/a&gt;. The &lt;a href="http://skylinq.azurewebsites.net/skylog" mce_href="http://skylinq.azurewebsites.net/skylog"&gt;Sky Log example&lt;/a&gt; has also been updated to use the efficient Top K algorithm.&lt;/p&gt;
  
&lt;p&gt;Note that this algorithm combined OrderBy and Take by GroupBy itself still uses O(N) splace where N is number of groups. There are &lt;a href="http://books.google.com/books?id=415loiMd_c0C&amp;amp;lpg=PP1&amp;amp;dq=Data%20Streams%3A%20Algorithms%20and%20Application&amp;amp;hl=el&amp;amp;pg=PA33#v=onepage&amp;amp;q&amp;amp;f=false" mce_href="http://books.google.com/books?id=415loiMd_c0C&amp;amp;lpg=PP1&amp;amp;dq=Data%20Streams%3A%20Algorithms%20and%20Application&amp;amp;hl=el&amp;amp;pg=PA33#v=onepage&amp;amp;q&amp;amp;f=false"&gt;probabilistic approximation algorithms&lt;/a&gt; that can be used to further alleviate memory foot print. That is something I could try in the future.&lt;/p&gt;
</description><pubDate>Wed, 15 Jan 2014 05:39:00 GMT</pubDate><guid isPermaLink="true">https://weblogs.asp.net:443/lichen/an-efficient-top-k-algorithm-with-implementation-in-c-for-linq</guid><category>.NET</category><category>C#</category><category>LINQ</category></item></channel></rss>