Sunny Ahuwanya's Blog

Mostly notes on .NET and C#

C# Brain teasers Part II

I’ve compiled a few C# brain teasers that you can explore interactively.
They are a tougher than the ones I posted previously but are only limited to the C# 2.0 feature set, to keep things simple.

Try to guess the answer to each question and then hit Go to evaluate the code.
The explanations for the answers are at the bottom of this post.

1)

//Can you guess what the output is?

for(int i = 0; i < 10; i++)
{
    Console.Write(i + ' '); 
}

Explanation

2)

//Class declarations

class Base
{
}

class A : Base
{
    public int Field;
}

class B : Base
{
    public int Field = 0;
    public static implicit operator A(B source)
    {
        return new A { Field = source.Field };
    }
}

// Is there anything wrong with the assignment below?

A obj = new B();

// Do any of these four statements compile?

/* 1. */ object[] oArr = new string[5];
/* 2. */ A[] aArr = new B[5];
/* 3. */ object[] oArr2 = new int[5];
/* 4. */ long[] dArr = new int[5];

Explanation

3)

//Can you guess what the output is?

struct Counter
{
    int counter;
    public override string ToString()
    {
        return counter++.ToString();
    }
}

Counter c = new Counter();
Console.WriteLine(c);
Object o = c;
Object r = o;
Console.WriteLine(c);
Console.WriteLine(r);
Console.WriteLine(o);
Console.WriteLine(o);
Console.WriteLine(r);

Explanation

4)

//What is wrong with this code?

class Outer
{
    static int sField = 0;

    public class Nested
    {
        public virtual int GetFieldValue()
        {
            return sField;
        }
    }
}

class SubClass : Outer.Nested
{
    public override int GetFieldValue()
    {
        return sField + 5;
    }
}

Explanation

5)

//What is the length of the strings?

string s1 = "\U0010FADE";
string s2 = "\U0000FADE";
Console.WriteLine(s1.Length);
Console.WriteLine(s2.Length);

Explanation

6)

//What is the output? i.e. the lengths of the arrays?

int[] singleDimension = {1,2,3,4};
int[,] multiDimension = {{1,2},{3,4}};
int[][] jagged = { new int[] { 1, 2 }, new int[] { 3, 4 } };

Console.WriteLine(singleDimension.Length);
Console.WriteLine(multiDimension.Length);
Console.WriteLine(jagged.Length);

Explanation

7)

//Class declarations

class Base
{
    protected class C
    {
        public C()
        {
            Console.WriteLine("Base.C()");
        }
    }
}

class A : Base
{
    public A()
    {
        Base.C inheritedC = new Base.C();
        C myC = new C();
    }

    new class C
    {
        public C()
        {
            Console.WriteLine("A.C()");
        }
    }
}

class B : A
{
    public B()
    {
        C implicitC = new C();
        Base.C baseC = new Base.C();
    }
}

//What is outputted when a new B object is created?

B b = new B();

Explanation

8)

// What is wrong with this code?

class B
{
    private static void M() { Console.WriteLine("B.M"); }
    public static void M(int i) { Console.WriteLine("B.M(int)"); }
}

class E
{
    static void M() { Console.WriteLine("E.M"); }
    static void M(int i) { Console.WriteLine("E.M(int)"); }

    class C : B
    {
        public static void Main()
        {
            M();
        }
    }
}

Explanation

9)

//Which field initializer statement(s) in the class will not compile?

class A
{
    bool a = false;
    object b = new A();
    bool c = a;
    object d = this; 
    int j = i + 1;
    static int i = 4;   
}

Explanation

10)

//What is wrong with this code?

class Generator
{
    readonly Random rnd;

    public Generator(ref Random RandomGenerator)
    {
        GetRandomGenerator(out rnd);
        RandomGenerator = rnd;
    }

    public void Reset(ref Random RandomGenerator)
    {
        GetRandomGenerator(out rnd);
        RandomGenerator = rnd;
    }

    private void GetRandomGenerator(out Random RandomGenerator)
    {
        RandomGenerator = new Random();
    }
}

Explanation

11)

// Why won't the code below compile?

class A
{
    private int i;

    public int P
    {
        get
        {
            return i;
        }
        set
        {
            i = value;
        }
    }

    public int get_P()
    {
        return i;
    }

    public void set_P(int i)
    {
        this.i = i;
    }
}

Explanation

12)

//Why won't the code below compile?

class A
{
    int Item = 0;

    public int this[params int[] arr]
    {
        get
        {
            return Item;
        }
    }
}

Explanation

13)

//What is the output?

float number = 23, zero = 0;

try
{
    Console.WriteLine(number / zero);
}
catch (DivideByZeroException)
{
    Console.WriteLine("Division By Zero");
}

Explanation

14)

//What is the output?

//Checked context
float fMax = float.MaxValue;
int iMax = int.MaxValue;
decimal decMax = decimal.MaxValue;
checked
{
    try
    {
        Console.WriteLine(fMax += 10);
    }
    catch { Console.WriteLine("Float Overflow"); }
    try
    {
        Console.WriteLine(iMax += 10);
    }
    catch { Console.WriteLine("Integer Overflow"); }
    try
    {
        Console.WriteLine(decMax += 10);
    }
    catch { Console.WriteLine("Decimal Overflow"); }
}

//Unchecked context
fMax = float.MaxValue;
iMax = int.MaxValue;
decMax = decimal.MaxValue;
unchecked
{
    try
    {
        Console.WriteLine(fMax += 10);
    }
    catch { Console.WriteLine("Float Overflow"); }
    try
    {
        Console.WriteLine(iMax += 10);
    }
    catch { Console.WriteLine("Integer Overflow"); }
    try
    {
        Console.WriteLine(decMax += 10);
    }
    catch { Console.WriteLine("Decimal Overflow"); }
}

Explanation

15)

// Class declaration

class B
{
    public B()
    {
        M1();
    }
    public virtual void M1()
    {
        Console.WriteLine("B.M1");
    }
}

class C : B
{
    int f;

    public C()
    {
        f = 7;
    }
    public override void M1()
    {
        Console.Write("C.M2 : " + f);
    }
}

// What is outputted when a new C object is created?

new C();

Explanation

16)

// Type declarations

class MyClass
{   
    private int PrivA;
    public int PubB;
    
    public MyClass(int a, int b)
    {
        this.PrivA = a;
        this.PubB = b;
    }
}

struct MyStruct
{    
    private int PrivA;
    public int PubB;
    
    public MyStruct(int a, int b)
    {
        this.PrivA = a;
        this.PubB = b;
    }
}

// What is outputted?

MyClass c1 = new MyClass(50, 99);
MyClass c2 = new MyClass(70, 99);
MyClass c3 = new MyClass(50, 99);

MyStruct s1 = new MyStruct(50, 99);
MyStruct s2 = new MyStruct(70, 99);
MyStruct s3 = new MyStruct(50, 99);

Console.WriteLine(c1.Equals(c2));
Console.WriteLine(c1.Equals(c3));

Console.WriteLine(s1.Equals(s2));
Console.WriteLine(s1.Equals(s3));

Explanation

 

Explanations:

A1.
The output is 32333435363738394041.
A char is a numeric value that is expressed as a character so 1 + ' ' is really 1 + 32.

 

A2.
The A obj = new B() assignment is legal since an implicit conversion exists between classes A and B.

The first statement will compile because the String class derives from the Object class and so qualifies as an implicit reference conversion.
The second statement will not compile because even though there is a user defined implicit conversion, only standard implicit reference conversions are considered for arrays.
The third statement will not compile because even though Int32 derives from the Object class, it is a value type and cannot partake in an implicit reference conversion.
The fourth statement will not compile because even though the Int32 type is implicitly convertible to the Int64 (long) type, they are both value types and arrays can only convert from reference types that qualify for an implicit reference conversion.

 

A3. 
The output is:

0
0
0
1
2
3

How’s that? This is a case of boxing and unboxing turned on its head.
When the ToString() method override is called, struct c is automatically boxed to an object type to facilitate the call. This stores a copy of c on the heap and calls ToString() on that copy.
Therefore the counter field on the actual struct c never changes. The counter field for struct c will always be 0, regardless of how many times ToString() is called.

Object o is a boxed copy of struct c and object r references the same boxed copy. When ToString() is called on either o or r, the boxed copy is accessed directly and the counter is incremented.
Thus calls to o.ToString() and r.ToString() increment the same referenced counter structure.
This shows that contrary to popular opinion, it is possible, even trivial, to modify a boxed value.

 

A4.
The static Outer.sField private field is accessible to class Nested but not accessible to class SubClass because the scope of a static member includes nested classes, but it excludes subclasses of the nested class.

A5.
The output is:
2
1

The \Udddddddd escape code is used for encoding UTF-16 unicode characters (also referred to as codepoints).
System.Char structures store 16 bit values (0x0000 through 0xFFFF) and so a single System.Char is unable to store unicode characters that fall within the 0x10000 and 0x10FFFF range.
To accommodate these characters, multiple System.Char structures are used.
This is the case for string s1, where two chars are used to store the unicode character.
In string s2, only one char stores the unicode character.

String.Length returns the number of System.Char structures in the string, not the number of unicode characters.

 

A6.
The output is:
4
4

 
The Length property of arrays returns the total number of elements in single and multi-dimensional arrays.
However, it returns only the number of elements in the first dimension of a jagged array.

 

A7. 
The output is:
Base.C()
A.C()
Base.C()
Base.C()

Nested class Base.C is marked with a protected modifier and so will be inherited by classes that derive from Base. This is similar to the way protected fields are inherited, except in this case it is the access to Base.C that is being inherited.
Class A is derived from Base and so inherits access to Base.C , but also defines a nested class called C, which hides Base.C.
Base.C is still accessible from within class A but must be referred to explicitly by Base.C.
Classes that derive from class A will have access to both Base.C and A.C. However, it's important to note that external access to A.C points to the inherited Base.C because the new class A.C is implicitly private and is only visible and accessible to code within class A.
Class B is derived from class A. It inherits access to Base.C and the externally visible A.C (which is actually Base.C), so variables implicitC and baseC refer to objects constructed from the same class.

If the new class A.C's access modifier is changed to protected i.e. protected new class C , the code will output
Base.C()
A.C()
A.C()
Base.C()
because B will now inherit access to the true class A.C. In fact, since class A.C is closer to class B than class Base.C in the inheritance hierarchy, A.C can be implicitly referred to as C, and so the variable implicitC now maps to an object constructed from class A.C whereas variable baseC will refer to an object constructed from class Base.C.

 

A8.

The call to M() in the Main method is not allowed. Even though there is an accessible static M() method in the enclosing class E, the call refers to the inaccessible B.M() method because inherited members of C are preferred over members of enclosing classes.
There is an accessible inherited method M(int i), so all calls to methods named M (of any signature) from class C will be mapped to the M methods in the base class B.

It's not possible to call an overload of a method in the base class and call another overload in the enclosing class.
The compiler will choose to call either all overloads in the base class (preferably) or all overloads in the enclosing class.
If you comment out the B.M(int i) method overload, then the static M method in the enclosing class is called.

 

A9.

These two statements will not compile:

bool c = a; //CS0236 A field initializer cannot reference the nonstatic field, method, or property 'field'
object d = this; //CS0027 Keyword this is not available in the current context

Outside a method, instance fields cannot be used to initialize other instance fields.
The this keyword is unavailable outside a method, property or constructor.
Interestingly, the field A.b that initializes a brand new object A is allowed.

 

A10.

The following line will not compile:

GetRandomGenerator(out rnd); //CS0192 A readonly field cannot be passed ref or out (except in a constructor)

A readonly field cannot be passed as a ref or out parameter (except in a constructor).
Constructors can accept ref and out parameters.

 

A11.

Properties are compiled into get_{Property_Name} and set_{Property_Name} methods.
The methods get_P and set_P will conflict with the generated property methods.

 

A12.

Indexers are compiled into a property named Item and methods named get_Item and set_Item.
The field Item conflicts with the generated property name.
It’s okay to have a params modifier in an indexer.

 

A13.

The output is:
Infinity

Only integral (int, long, short, byte, uint, ulong, ushort, sbyte, char) and the decimal types throw a DivisionByZero exception when divided by zero.
Float and Double types will return special IEEE754 values such as Infinity or NaN.

 

A14.

The output is:

3.402823E+38
Integer Overflow
Decimal Overflow
3.402823E+38
-2147483639
Decimal Overflow

Overflows in integral (int, long, short, byte, uint, ulong, ushort, sbyte, char) types wrap around in an unchecked context. In a checked context they throw an overflow exception.
Overflows in floating point (float and double) types always wrap around and never throw an overflow exception in any context. They can also produce special IEEE754 values such as Infinity or NaN as results.
Overflows in the decimal type always throw an overflow exception in any context.

 

A15.

The output is:
C.M2 : 0

When C's constructor is called, It implicitly calls the base constructor before the field f assignment.
B's constructor calls the M1 method, a virtual-instance method, which resolves to method C.M1.
At the point when C.M1 is called from B's constructor, the value of field f has not been assigned yet and is the default value of zero. 

 

A16.

The output is:

False
False
False
True

By default the Equals method compares references in reference types. i.e returns true if both variables refer to the same object.
In value types, it will compare the types of the variables. If they are not the same, it returns false.
If they are the same type, it will compare the value of each field (including private ones).

Introducing C# Pad

I’m excited to present C# Pad, an interactive web based C# REPL.

Have you ever wanted to quickly evaluate an expression or test some code, like say try out different DateTime string formats or test a method or clear up some confusion (like what’s the difference between Uri.EscapeDataString and Uri.EscapeUriString or what new Random().Next(0) returns), or decode some string in Base64 or some other format?

C# Pad lets you easily do all those things and a whole lot more.

Interactive REPL

Do you see the embedded code pad below? Go ahead and hit the Go button.

var greeting = "こんにちは世界";
Console.WriteLine("{0} in Japanese is {1}", "Hello World", greeting);

After the submission is processed, you’ll see the result of the code evaluation.
Now, in the same code pad, type Console.WriteLine(greeting.Length) and hit Go.

As you can see, the greeting variable from the previous submission is accessible in the code editor.
That’s because C# Pad is a REPL. Objects in previous submissions are visible and accessible from the current one.
( Did you also notice the cool code completion? :) )

You don’t need to call Console.WriteLine to display results. Simply type the variable name (without a semicolon) in the last line of a code submission and the string representation of the variable’s value will be displayed. 
For example, type greeting in the same code pad and hit Go to see its value.

The following code pad contains a method that encodes an input string in Base64 format.

using System.IO;
using System.Text;

string Base64Encode(string input)
{
    if(input == null) throw new ArgumentNullException("input");
    
    var bytes = Encoding.UTF8.GetBytes(input);
    return Convert.ToBase64String(bytes);
}

Hit Go to submit the method and then type Base64Encode("My string") (do not include a semicolon) and hit Go.

You’ll observe the result is a string in Base64 format, encoded by the method that was defined in an earlier submission. Because the semicolon was left out, the result of the evaluation was displayed.

You can use C# Pad to write complex code, define classes and methods and evaluate all kinds of expressions ranging from simple mathematical expressions like 60 * 60 * 24 or Math.Sin((30 * Math.PI)/ 180) to LINQ expressions.

(from c in "The quick brown fox jumps over the lazy dog".ToLower()
group c by c into grp
select new { Letter = grp.Key, Count = grp.Count() }).ToArray()

C# Everywhere

You can embed interactive code pads in your blog, website or any site you can edit, just like I have in this blog post. You can even select a theme that matches your site.
Yes, this means you can now create a C# playground anywhere. Simply visit csharppad.com, compose the code you’d like to embed, click the embed button and follow the instructions.  

Here’s an example JSBin with an embedded code pad.

You can also load and save Github Gists.
To load a Gist, open csharppad.com/gist/_gist_owner_/_gist_id or simply csharppad.com/gist/_gist_id

As examples, the links below open up Gists in C# Pad.

http://csharppad.com/gist/9220821
http://csharppad.com/gist/octocat/1169852 ( Did you know The Octocat codes in C#? )

To open a single file in a Gist, append ?file_name at the end of the url, like so
http://csharppad.com/gist/9220821?random.cs

Numerical Analysis

The awesome Math.Net Numerics library is bundled with C# Pad, which makes working on complex math and statistics problems a breeze.

The following program integrates the function f(x) = exp(-x/5) (2 + sin(2 * x)) on a closed interval of [0, 100].

using MathNet.Numerics;
Integrate.OnClosedInterval(x => Math.Exp(-x / 5) * (2 + Math.Sin(2 * x)), 0, 100)


The following program generates ten samples of a Poisson distribution with a lambda parameter of 1.

using MathNet.Numerics.Distributions;
var poisson = new Poisson(1);
for(var i = 0; i < 10; i++)
{
    Console.WriteLine("{0:N05}", poisson.Sample());
}


The following program calculates the 75th percentile of an array of numbers.

using MathNet.Numerics;

var percentile = 75;
var array = new double[]{ 89.6, 33.5, 11.6, 44.3, 66.78, 34.78, 97.1, 68.0, 25.7, 48.7};

ExcelFunctions.Percentile(array, percentile / 100d)


The following program multiplies the transpose of a matrix with another matrix.

using MathNet.Numerics.LinearAlgebra.Double;

var matrixA = DenseMatrix.OfArray(new[,] { { 1.0, 2.0, 3.0 }, { 4.0, 5.0, 6.0 }, { 7.0, 8.0, 9.0 } 
});
var matrixB = DenseMatrix.OfArray(new[,] { { 1.0, 3.0, 5.0 }, { 2.0, 4.0, 6.0 }, { 3.0, 5.0, 7.0 } });

matrixA.Transpose() * matrixB

//Same as matrixA.TransposeThisAndMultiply(matrixB)

 

C# Pad is the first and only (as of this writing) web based interactive C# REPL, with code completion, diagnostics, themes, embeddability, timing information, Gist support and more features to come.

I hope you find C# Pad useful and delightful. Drop me a line or use the help link on the site to provide feedback on feature suggestions, bug reports and other kinds of feedback.

Have fun!

Multi-Slab Buffers

A noteworthy feature of the bufferpool project is the ability for an individual buffer to span multiple slabs.

Previously, a buffer was confined to one slab, meaning that the maximum buffer size was the slab size.
It was impossible to send or receive data that was larger than the slab.
This commit changed that. Individual buffers can now span multiple slabs, which allows for what is known as Scatter/Gather or Vectored I/O operations.

Buffer spanning multiple slabs


This means buffers of any arbitrary length can be requested from the pool and all needed slabs will be created and added to the pool, to form the buffer.
Conversely, the slabs are freed and removed from the pool, when the buffer is disposed.

This feature is particularly useful for transmitting or receiving large amount of data. It eliminates the need to allocate a large contiguous memory block to hold the data.
Instead, smaller slabs, which are allocated at different convenient locations in memory, are chained to form the buffer.
This significantly lessens the chance of running out of memory, due to heap fragmentation, during socket operations involving a large amount of data.

Enumerating AppDomains from a CLR Host

If you’ve ever tried to enumerate the appdomains in your application, you would have discovered that it’s not exactly an easy task. It’s even more difficult if you try to enumerate the appdomains from an unmanaged CLR host.
I was faced with this task recently and decided to blog about how circuitous it can be.

The obvious solution is to use the ICorRuntimeHost::EnumDomains method, however, the ICorRuntimeHost hosting interface was deprecated and superceded by the CLR v2 ICLRRuntimeHost interface, which does not provide a means to enumerate appdomains.

That’s okay, there are other options available, one of which is to use the ICorPublishProcess::EnumAppDomains method.
To do so, first get an ICorPublishProcess instance that represents the current process, like so:

ICorPublish* pPub = NULL;
ICorPublishProcess* pCurrProcess = NULL;

HRESULT hr = CoCreateInstance (CLSID_CorpubPublish, NULL, CLSCTX_INPROC_SERVER, IID_ICorPublish,(LPVOID *)&pPub);

DWORD cpid = GetCurrentProcessId();
hr = pPub->GetProcess(cpid, &pCurrProcess);

And then pass that instance to the following function.

void EnumAppDomains (ICorPublishProcess *pProcess)
{
    #define NAME_LEN 261

    // Enumerate the application domains.
    ICorPublishAppDomainEnum* pEnumDomains;
    HRESULT hr = pProcess->EnumAppDomains(&pEnumDomains);
    if (SUCCEEDED(hr))
    {
        ICorPublishAppDomain* appDomains[1];
        ULONG aFetched = 1;
		ULONG32 nId;
        while (aFetched > 0 && pEnumDomains->Next(1,appDomains, &aFetched) == S_OK)
        {
			// Display information about each domain.
			if (aFetched > 0)
			{
				appDomains[0]->GetID(&nId);

				WCHAR name[NAME_LEN];
				ULONG32 size=0;
				appDomains[0]->GetName(NAME_LEN, &size, name);
				if (size > 0)
				{
					wprintf(L"name = %s , id = %Iu\n", name, nId);
				} 
				appDomains[0]->Release();
			}

        }
        pEnumDomains->Release();
    }
}

So far, so good. Looks like we’re done here except that there are a few lingering issues:

You have to make sure you are instantiating the right version of ICorPublish for the version of the CLR you’re running, or else you’ll run into some issues as discussed here and here.

The more significant drawback is that you have to call CoCreateInstance as seen in the first code listing. This means you are creating a COM object and you really should call CoInitializeEx(NULL, COINIT_MULTITHREADED) when your host starts, to properly initialize the the COM library.
You’re now knee deep in COM land and have to deal with COM related issues if you choose this route.

An approach that avoids initializing COM involves using the ICLRDebugging interface which can be instantiated with the CLRCreateInstance function. Once instantiated, make a call to OpenVirtualProcess method to obtain an ICorDebugProcess interface and then call ICorDebugProcess::EnumerateAppDomains to enumerate the appdomains in the process.

I don’t like this approach because it’s a *debugging* API and seems excessive for the objective.
So what other options do we have left? Let’s revisit the ICorRuntimeHost interface. It’s deprecated but that doesn’t mean it can no longer be used.
Using this interface is pretty straightforward and there are good examples (.NET 2 version) available on how to use it. The only snag is that my application already makes use of the newer ICLRRuntimeHost interface and I don’t want to replace it with the ICorRuntimeHost interface. I need the older interface to enumerate appdomains and the newer interface for all other hosting related tasks.

Fortunately, you can obtain the two interfaces from the same runtime as shown in this MSDN forum discussion. Here’s an excerpt of the relevant code.

#include"stdafx.h"
#include<mscoree.h>
#include<metahost.h>
#pragmacomment(lib, "mscoree.lib")

int _tmain(int argc, _TCHAR* argv[])
{
	HRESULT hr;
	ICLRMetaHost *pMetaHost = NULL;
	hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_ICLRMetaHost, (LPVOID*)&pMetaHost);
	ICLRRuntimeInfo * lpRuntimeInfo = NULL;
	hr = pMetaHost->GetRuntime(L"v4.0.30319", IID_ICLRRuntimeInfo, (LPVOID*)&lpRuntimeInfo);
	ICLRRuntimeHost * lpRuntimeHost = NULL;
	hr = lpRuntimeInfo->GetInterface(CLSID_CLRRuntimeHost, IID_ICLRRuntimeHost, (LPVOID *)&lpRuntimeHost);
	hr = lpRuntimeHost->Start();
	ICorRuntimeHost* lpCorRuntimeHost = NULL;
	hr = lpRuntimeInfo->GetInterface(CLSID_CorRuntimeHost, IID_ICorRuntimeHost, (LPVOID *)&lpCorRuntimeHost);
	// To do.
	return 0;
}

One thing I discovered while trying out the code above is that you have to start the runtime first ( lpRuntimeHost->Start() ) before obtaining the second interface. All my attempts to obtain the second interface before starting the runtime failed.

If you don’t have a pointer to the runtime, you can inspect the process using the ICLRMetaHost interface to get the loaded runtimes as shown below.

HRESULT GetV1CorRuntimeHost(ICorRuntimeHost** ppCorRuntimeHost){

    IEnumUnknown* pRuntimeEnum = NULL;
    ICLRMetaHost* pMetaHost = NULL;
    IUnknown* pClrRunTimeInfoThunk = NULL;
    ICLRRuntimeInfo* pClrRunTimeInfo = NULL;

    //Get the ICLRMetaHost interface
    HRESULT hr = CLRCreateInstance(CLSID_CLRMetaHost, IID_PPV_ARGS(&pMetaHost));
    if (FAILED(hr))
    {
        wprintf(L"GetV1CorRuntimeHost: CLRCreateInstance CLRMetaHost failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
    }

    //Get the runtime enumerator
    hr = pMetaHost->EnumerateLoadedRuntimes(GetCurrentProcess(),&pRuntimeEnum);
	if (FAILED(hr))
    {
        wprintf(L"GetV1CorRuntimeHost: EnumerateLoadedRuntimes failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
    }

    //Get the first loaded runtime
    ULONG fetched = 0;
    hr = pRuntimeEnum->Next(1, &pClrRunTimeInfoThunk, &fetched);
    if (FAILED(hr))
    {
        wprintf(L"GetV1CorRuntimeHost: pRuntimeEnum->Next failed w/hr 0x%08lx\n", hr);
		goto Cleanup;
    }

    if(fetched != 1)
    {
	wprintf(L"GetV1CorRuntimeHost: Runtime could not be fetched");
	hr = E_FAIL;
	goto Cleanup;
    }

    //Get the ICLRRuntimeInfo object
    hr = pClrRunTimeInfoThunk->QueryInterface(IID_PPV_ARGS(&pClrRunTimeInfo));
    if (FAILED(hr))
    {
        wprintf(L"GetV1CorRuntimeHost: Failed to get the ICLRRuntimeInfo object w/hr 0x%08lx\n", hr);
		goto Cleanup;
    }

    //Get the ICorRuntimeHost interface
    *ppCorRuntimeHost = NULL;
    hr = pClrRunTimeInfo->GetInterface(CLSID_CorRuntimeHost, 
    IID_PPV_ARGS(ppCorRuntimeHost));
    if (FAILED(hr))
    {
        wprintf(L"GetV1CorRuntimeHost: GetInterface(CLSID_CorRuntimeHost) failed w/hr 0x%08lx\n", hr);
	goto Cleanup;
    } 

    hr = S_OK;

Cleanup:

    if(pClrRunTimeInfo) pClrRunTimeInfo->Release();
    if(pClrRunTimeInfoThunk) pClrRunTimeInfoThunk->Release();
    if(pRuntimeEnum) pRuntimeEnum->Release();
    if(pMetaHost) pMetaHost->Release();

	return hr;
	
}

Obtaining the ICorRuntimeHost interface is now as easy as

ICorRuntimeHost *pCorRuntimeHost = NULL;
HRESULT hr = GetV1CorRuntimeHost(&pCorRuntimeHost);

Henceforth, it’s easy to enumerate the appdomains as shown in this blog post.
Here’s an excerpt of the relevant code (substituting the ICorRuntimeHost variable name to match the name used in this post)

// Enumerate the AppDomains
HDOMAINENUM adEnum;
hr = pCorRuntimeHost->EnumDomains(&adEnum);
EXITONERROR(hr, "Unable to enumerate AppDomains");

// Loop thru the domains
IUnknown * pDomainUnk = NULL;
hr = pCorRuntimeHost->NextDomain(adEnum, &pDomainUnk);
while(SUCCESSFUL(hr))
{
    // Got the IUnknown* to the AppDomain - convert it to AppDomain pointer
    _AppDomain * pCurDomain = NULL;
    hr = pDomainUnk->QueryInterface(__uuidof(_AppDomain), (VOID**)&pCurDomain);
    if (SUCCESSFUL(hr))
    {
        // Display the name of the AppDomain
        BSTR str;
        if (SUCCESSFUL(pCurDomain->get_FriendlyName(&str)))
        {
        wprintf(L"AppDomain: %s\n",str);
        }
        else
        {
            printf("AppDomain: unable to get the name!\n");
        }
    } 

    // Loop onto the next Domain
    hr = pCorRuntimeHost->NextDomain(adEnum, &pDomainUnk);
}

StackOverflowException and the x64 platform

The StackOverflowException is one of the three deadly exceptions. The other two being the OutOfMemoryException and the ThreadAbortException. These exceptions are deadly because they can theoretically occur anywhere in an application and terminate the process. Also, developers hardly ever prepare for them and are caught unawares when they occur.

Of these three, the StackOverflowException is arguably the deadliest because it cannot be caught when it is thrown by the runtime. 
That's right. When a StackOverflowException is thrown by the runtime (not when it is thrown by the application), try blocks are not processed and the program is promptly terminated. This is the default behavior and cannot be changed unless there is a custom CLR host involved.

This is conventional .NET wisdom that has been time tested and proven, so you can imagine my surprise when a condition that should have caused a StackOverflowException and subsequent process termination, did not.

If you compile following code, target the x86 platform in release mode and run it from your desktop:

class Program
{
    static void Main(string[] args)
    {
        CauseStackOverflow();
    }

    static void CauseStackOverflow()
    {
        CauseStackOverflow();	
    }
}

The program will terminate after encountering a StackOverflowException.

image

However, if you compile the same program targeting the x64 platform in release mode, and run it from your desktop (not from Visual Studio which attaches a debugger), the program keeps running. The StackOverflowException is not thrown and the program never terminates.

After some investigation, it turns out that the JIT compiler on the x64 will perform tail call optimization for such code and so will never overflow the stack!

These blog posts by David Broman go into detail on tail call optimization in the CLR.

If I create a condition that prevents the optimization like modifying the recursed method to return a value type:

class Program
{
    static void Main(string[] args)
    {
        CauseStackOverflow();
    }

    static int CauseStackOverflow()
    {
        return CauseStackOverflow();
	
    }
}

The StackOverflowException occurs on the x64 platform and the process terminates as expected.

Testing the BufferPool Project

One of the challenges I faced while working on the BufferPool project was verifying that it worked perfectly. Although I wrote a bunch of unit tests to assert the right behavior, I couldn’t conclude that it actually ensured that buffers were pinned within a pre-defined contiguous memory block.

To confirm this, I manually compared memory dumps from a process that used the library with dumps from another one that did not.

Two programs were used to perform this test. The first program is a variant of the asynchronous socket listener sample on MSDN, modified to call GC.Collect upon accepting a fifth connection. It also creates a long empty byte array on each new connection to simulate other memory allocations that typically take place during the read callback (which isn’t triggered during the test).

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;

namespace BufferPinningTester
{

    public class AsynchronousSocketListener
    {
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        static int connectCount = 0;

        public static void StartListening()
        {
            // Establish the local endpoint for the socket.
            // The DNS name of the computer
            // running the listener is "host.contoso.com".
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                    connectCount++;

                    if (connectCount == 5)
                    {
                        GC.Collect();
                        Console.WriteLine("GC Collected");
                    }
                    
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();

        }

        public static void AcceptCallback(IAsyncResult ar)
        {

            Console.WriteLine("In AcceptCallback");
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the state object.
            StateObject state = new StateObject();
            //create some random array
            byte[] b = new byte[StateObject.BufferSize];
            state.workSocket = handler;
            handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0,
                new AsyncCallback(ReadCallback), state);
        }

        public static void ReadCallback(IAsyncResult ar)
        {
            Console.WriteLine("In ReadCallback");

            String content = String.Empty;

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            
            // Read data from the client socket. 
            int bytesRead = handler.EndReceive(ar);

            return;

        }

        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }


// State object for receiving data from remote device.
public class StateObject {
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 16000;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}



}

The second program is a version of the first program modified to use a buffer pool. In this program, The 16KB buffer allocations are managed by the pool.

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Net;
using System.Net.Sockets;
using ServerToolkit.BufferManagement;

namespace BufferPinningTester
{

    public class AsynchronousSocketListener
    {
        public static ManualResetEvent allDone = new ManualResetEvent(false);
        static int connectCount = 0;
        static BufferPool pooledBuffers = new BufferPool(80000, 1, 1);
        

        public static void StartListening()
        {
            // Establish the local endpoint for the socket.
            // The DNS name of the computer
            // running the listener is "host.contoso.com".
            IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
            IPAddress ipAddress = ipHostInfo.AddressList[0];
            IPEndPoint localEndPoint = new IPEndPoint(ipAddress, 11000);

            // Create a TCP/IP socket.
            Socket listener = new Socket(AddressFamily.InterNetwork,
                SocketType.Stream, ProtocolType.Tcp);

            // Bind the socket to the local endpoint and listen for incoming connections.
            try
            {
                listener.Bind(localEndPoint);
                listener.Listen(100);

                while (true)
                {
                    // Set the event to nonsignaled state.
                    allDone.Reset();

                    // Start an asynchronous socket to listen for connections.
                    Console.WriteLine("Waiting for a connection...");
                    listener.BeginAccept(
                        new AsyncCallback(AcceptCallback),
                        listener);

                    // Wait until a connection is made before continuing.
                    allDone.WaitOne();
                    connectCount++;

                    if (connectCount == 5)
                    {
                        GC.Collect();
                        Console.WriteLine("GC Collected");
                    }
                    
                }

            }
            catch (Exception e)
            {
                Console.WriteLine(e.ToString());
            }

            Console.WriteLine("\nPress ENTER to continue...");
            Console.Read();

        }

        public static void AcceptCallback(IAsyncResult ar)
        {

            Console.WriteLine("In AcceptCallback");
            // Signal the main thread to continue.
            allDone.Set();

            // Get the socket that handles the client request.
            Socket listener = (Socket)ar.AsyncState;
            Socket handler = listener.EndAccept(ar);

            // Create the state object.
            StateObject state = new StateObject();
            //create some random array
            byte[] b = new byte[StateObject.BufferSize];
            state.workSocket = handler;
            IBuffer readBuffer = pooledBuffers.GetBuffer(StateObject.BufferSize);
            handler.BeginReceive(readBuffer.GetArraySegment(), 0,
                new AsyncCallback(ReadCallback), state);
        }

        public static void ReadCallback(IAsyncResult ar)
        {
            Console.WriteLine("In ReadCallback");

            String content = String.Empty;

            // Retrieve the state object and the handler socket
            // from the asynchronous state object.
            StateObject state = (StateObject)ar.AsyncState;
            Socket handler = state.workSocket;

            
            // Read data from the client socket. 
            int bytesRead = handler.EndReceive(ar);

            return;

        }

        public static int Main(String[] args)
        {
            StartListening();
            return 0;
        }
    }


// State object for receiving data from remote device.
public class StateObject {
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 16000;
    // Receive buffer.
    //public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
}



}

The test procedure consists of running the socket listener program and connecting to it from five telnet clients simultaneously.
A memory snapshot is taken before the fifth connection is made and another snapshot is taken after it is made. Both snapshots are then compared.
The test is conducted twice, once for each socket listener program.
To take these snapshots, you’ll need to use WinDbg debugger tool coupled with the Son of Strike (SOS) debugging extension.

In Detail:

  • Run the first socket listener program.
  • Run WinDbg and attach the socket listener process.
  • Load Son of Strike (SOS) from WinDbg by executing .loadby sos clr (if you are working with .NET 2.0/3.5, execute .loadby sos mscorwks instead).
  • Execute g to continue running the program.
  • Connect four telnet clients to port 11000 (the socket listener port).
    While running telnet, it’s important not to hit any key after telnet makes the connection, so as not to transmit any data and keep the buffer pinned. If you see a "In ReadCallback" message in the socket listener console window, it means data was transmitted – we don’t want that.
  • Press ctrl-break in WinDbg to halt execution of the program.
  • Execute the !gchandles command to get information about asynchronous pinned handles.
  • Execute the !dumpheap command to get a memory snapshot of objects in the heap.
  • Execute g to continue running the program.
  • Connect the fifth telnet client.
  • You should see "GC Collected" in the socket listener program console window.
  • Press ctrl-break in WinDbg to halt execution of the program.
  • Execute the !gchandles command to get information about asynchronous pinned handles.
  • Execute the !dumpheap command to get a memory snapshot of objects in the heap.
  • Run the test again, this time for the second socket listener program.

A sample output from !gchandles is shown below. The number of asynchronous pins are highlighted.

0:005> !gchandles
*********************************************************************
* Symbols can not be loaded because symbol path is not initialized. *
*                                                                   *
* The Symbol Path can be set by:                                    *
*   using the _NT_SYMBOL_PATH environment variable.                 *
*   using the -y <symbol_path> argument when starting the debugger. *
*   using .sympath and .sympath+                                    *
*********************************************************************
PDB symbol for mscorwks.dll not loaded
GC Handle Statistics:
Strong Handles: 37
Pinned Handles: 6
Async Pinned Handles: 4
Ref Count Handles: 0
Weak Long Handles: 35
Weak Short Handles: 10
Other Handles: 0
Statistics:
              MT    Count    TotalSize Class Name
000007fef8ac7370        1           24 System.Object
000007fef92a2f88        1           32 System.Threading.RegisteredWaitHandle
000007fef8ac87c0        1           48 System.SharedStatics
000007fef8ac8078        1          136 System.ExecutionEngineException
000007fef8ac7f68        1          136 System.StackOverflowException
000007fef8ac7e58        1          136 System.OutOfMemoryException
000007fef8ac8980        1          192 System.AppDomain
000007fef92a3040        5          200 System.Threading._ThreadPoolWaitOrTimerCallback
000007fef8aca540        5          240 System.Reflection.Assembly
000007fef8ab5d68        5          240 System.Threading.ManualResetEvent
000007fef76be9b0        4          256 System.Net.Logging+NclTraceSource
000007fef8ac8188        2          272 System.Threading.ThreadAbortException
000007fef76d59a8        4          288 System.Diagnostics.SourceSwitch
000007fef8ac43f8        4          384 System.Reflection.Module
000007fef8ac8520        4          416 System.Threading.Thread
000007fef8ace270        7          448 System.Security.PermissionSet
000007fef8699058        4          480 System.Threading.OverlappedData
000007fef8ac4558       35         5040 System.RuntimeType+RuntimeTypeCache
000007fef8ab5870        6        33856 System.Object[]
Total 92 objects
  

You now have useful output from the !dumpheap and !gchandles commands for both programs.
You can download the !dumpheap and !gchandles output from my tests here.
You’ll notice that the output from dumpheap after garbage collection is much smaller than the output before garbage collection. That’s because garbage collection got rid of stale objects in memory.

If you compare the two !dumpheap output listings from the first (unpooled) test, you can easily verify that all memory addresses that hold byte arrays that are at least 16,000 bytes long were collected by the GC except for four addresses. You can tell that a memory address holds a byte array if its MT (MethodTable) address is the one for System.Byte[] in the statistics section at the bottom of the !dumpheap listings. On my system, the MT for System.Byte[] is 000007fef8acfac0.
The output from !gchandles shows that there were four asynchronous pins before garbage collection and five after garbage collection. This observation strongly suggests that those empty byte arrays that were created were collected while the pinned buffer byte arrays were not.

Now let’s take a look at the memory behavior of the pooled test by comparing its two !dumpheap output listings before and after garbage collection. The desired behavior with pooled buffers is that all pinned addresses are within one long byte array.
You’ll observe that all byte arrays in the heap are collected except one, and that one is 92 KB long.
The pooler creates a minimum pool size of 92 KB so as to force .NET to allocate the array in the large object heap.
The output from !gchandles shows that there were four asynchronous pins before garbage collection and five after garbage collection. Since only byte arrays were pinned, it means they all occurred within the 92k byte array block!
We have verified that the pooler is working correctly.

To see details of the 92KB block, run the !dumpobj command on the block’s memory address:

0:005> !dumpobj 00000000127b9060
Name: System.Byte[]
MethodTable: 000007fef8acfac0
EEClass: 000007fef86d2680
Size: 92184(0x16818) bytes
Array: Rank 1, Number of elements 92160, Type Byte
Element Type: System.Byte
Fields:
None
  

Buffer Pooling for .NET Socket Operations

The terrific Garbage Collector in the .NET runtime is a compacting one. This means it moves memory blocks in use closer to each other during garbage collection, thus increasing the overall size of contiguous free memory and lessening the chance of running out of memory due to heap fragmentation.
This is pretty important for memory intensive applications as it is a nice guarantee that free contiguous memory will always be available whenever a large object needs to be allocated.

Whenever you perform send or receive socket operations in .NET, the buffer that holds the transmitted or received data is pinned by the .NET runtime. Pinning basically means that the region in memory that holds the data is locked down and is not eligible to be moved around by the Garbage Collector. This is necessary so that the Windows Socket API which handles the actual socket operation (and lives outside managed code) can access the buffer memory locations reliably. This pinning takes place regardless of if the operation is synchronous or asynchronous.

If you are building a memory intensive server application that is expected to serve thousands of clients concurrently, then you have a simmering problem waiting to blow up as soon as the server starts serving a non-trivial number of clients.
Thousands of sockets performing receive and/or send operations will cause thousands of memory locations to be pinned. If your server stores a lot of data in memory, you can have a fragmented heap that even though collectively has enough free memory to store a large object, is unable to do so, because there isn’t enough memory in a contiguous free block to store it. This is illustrated below: 

unpinned memory 
The diagram above depicts the common scenario where a large object is about to be allocated in memory. There is insufficient contiguous memory to store the object, which triggers garbage collection. During garbage collection, the memory blocks in use are compacted, freeing enough room to store the large object. 

pinned memory 
The diagram above depicts the same scenario with some objects pinned. The garbage collector compacts objects that are not pinned which makes some room, but not enough room due to the unmovable pinned objects. The end result is that a nasty Out Of Memory exception is thrown by the runtime because there is no contiguous free memory space large enough for the large object to be allocated.

This problem is discussed at length in this blog post and in this blog post. The solution to the problem, as noted in those posts, is to pre-allocate buffers. This basically means setting up a byte array which your sockets will use to buffer data. If all your socket operations use buffers from the designated byte array, then only memory locations within the region where the byte array is stored will be pinned, giving the GC greater freedom to compact memory.
However, for this to work effectively with multiple asynchronous socket operations, there has to be some kind of buffer manager that will dish out different segments of the array to different operations and ensure that buffer segments allotted for one operation are not used by a different operation until they are marked as no longer in use.

I searched for existing solutions for this problem but I couldn’t find any that was sufficiently adequate, so I wrote one that was robust and dependable. The solution is part of my ServerToolkit project, which is a set of useful libraries that can be used to easily build scalable .NET servers. The solution is called BufferPool and is the first ServerToolkit sub-project.

The idea is that you have a buffer pool that is a collection of memory blocks (byte arrays) known as slabs that you can grab buffers from. You decide the size of the slab and the initial number of slabs to create.
As you request buffers from the pool, it internally allocates segments within the slabs for use by your buffer. If you need more buffers than are available within the pool, new slabs are created and are added to the pool. Conversely, as you dispose your buffers, slabs within the pool will be removed when they no longer contain any allocated segments.  
 
buffer pool

USING BUFFER POOLING IN YOUR APPLICATION

Download the code from http://github.com/tenor/ServerToolkit/tree/master/BufferPool

Compile it to a DLL and reference the DLL from your project
OR
Add the project to your solution and reference the ServerToolkit.BufferManagement project from your main project.

In the code file that performs socket operations, add

using ServerToolkit.BufferManagement;

Create a buffer pool when your application starts with

BufferPool pool = new BufferPool(1 * 1024 * 1024, 1, 1);

This creates a pool that will have 1 MB slabs with one slab created initially. Subsequent slabs, if needed, will be created in increments of one.

It is advisable to create the pool as soon as your server application starts or at least before it begins any memory-intensive operations.

To use the pool in synchronous send and receive socket operations

/** SENDING DATA **/

// const int SEND_BUFFER_SIZE is the desired size of the send buffer in bytes 
// byte[] data contains the data to be sent.

using (var buffer = pool.GetBuffer(SEND_BUFFER_SIZE)) 
{ 
    buffer.FillWith(data); 
    socket.Send(buffer.GetSegments()); 
}


/** RECEIVING DATA **/

// const int RECEIVE_BUFFER_SIZE is the desired size of the receive buffer in bytes 
// byte[] data is where the received data will be stored.

using (var buffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE)) 
{ 
    socket.Receive(buffer.GetSegments()); 
    buffer.CopyTo(data); 
}

To use the pool for asynchronous send and receive socket operations

Sending data:

/** SENDING DATA ASYNCHRONOUSLY **/

// const int SEND_BUFFER_SIZE is the desired size of the send buffer in bytes 
// byte[] data contains the data to be sent.

var buffer = pool.GetBuffer(SEND_BUFFER_SIZE); 
buffer.FillWith(data); 
socket.BeginSend(buffer.GetSegments(), SocketFlags.None, SendCallback, buffer);

//...


//In the send callback.

private void SendCallback(IAsyncResult ar) 
{ 
    var sendBuffer = (IBuffer)ar.AsyncState; 
    try 
    { 
        socket.EndSend(ar); 
    } 
    catch (Exception ex) 
    { 
        //Handle Exception here 
    } 
    finally 
    { 
        if (sendBuffer != null) 
        { 
            sendBuffer.Dispose(); 
        } 
    } 
}

Receiving data:

/** RECEIVING DATA ASYNCHRONOUSLY **/

// const int RECEIVE_BUFFER_SIZE is the desired size of the receive buffer in bytes. 
// byte[] data is where the received data will be stored.

var buffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE); 
socket.BeginReceive(buffer.GetSegments(), SocketFlags.None, ReadCallback, buffer);

//...


//In the read callback

private void ReadCallback(IAsyncResult ar) 
{ 
    var recvBuffer = (IBuffer)ar.AsyncState; 
    int bytesRead = 0;

    try 
    { 
        bytesRead = socket.EndReceive(ar); 
        byte[] data = new byte[bytesRead > 0 ? bytesRead : 0];

        if (bytesRead > 0) 
        { 
            recvBuffer.CopyTo(data, 0, bytesRead);

            //Do anything else you wish with read data here. 
        } 
        else 
        { 
            return; 
        }

    } 
    catch (Exception ex) 
    { 
        //Handle Exception here 
    } 
    finally 
    { 
        if (recvBuffer != null) 
        { 
            recvBuffer.Dispose(); 
        } 
    }

    //Read/Expect more data                    
    var buffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE); 
    socket.BeginReceive(buffer.GetSegments(), SocketFlags.None, ReadCallback, buffer);

} 

There is a performance penalty involved when using the code above. Each time you perform a socket operation, you create a new buffer, use it and then dispose it. These actions involve multiple lock statements, and can become a bottleneck on the shared pool.

There is an optimization that can help mitigate this issue. The optimization is based on the way socket operations work. You can send data any time you like on a socket, but you typically receive data in a loop. i.e. receive data, signal that you are ready to receive more data and repeat. This means that each socket works with only one receive buffer at a time.
With this in mind, you can assign each socket a receive buffer of its own.  Each socket will use its receive buffer exclusively for all its receive operations, thereby avoiding the need to create and dispose a new buffer for each receive operation.
You have to dispose the receive buffer when you close the socket.

I recommend the pattern below.

/** RECEIVING DATA ASYNCHRONOUSLY (OPTIMIZED) **/

// const int RECEIVE_BUFFER_SIZE is the desired size of the receive buffer in bytes.

// const int BUFFER_SIZE_DISPOSAL_THRESHOLD specifies a size limit, which if exceeded by a buffer
// would cause the buffer to be disposed immediately after a receive operation ends.
// Its purpose is to reduce the number of large buffers lingering in memory.

// IBuffer recvBuffer is the receive buffer associated with this socket.

// byte[] data is where the received data will be stored.

// object stateObject holds any state object that should be passed to the read callback. 
// It is not necessary for this sample code.

if (recvBuffer == null || recvBuffer.IsDisposed)
{
    //Get new receive buffer if it is not available.
    recvBuffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE);
}
else if (recvBuffer.Size < RECEIVE_BUFFER_SIZE)
{
    //If the receive buffer size is smaller than desired buffer size,
    //dispose receive buffer and acquire a new one that is long enough.
    recvBuffer.Dispose();
    recvBuffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE);
}

socket.BeginReceive(recvBuffer.GetSegments(), SocketFlags.None, ReadCallback, stateObject);

//...


//In the read callback

private void ReadCallback(IAsyncResult ar)
{
    int bytesRead = socket.EndReceive(ar);

    byte[] data = new byte[bytesRead > 0 ? bytesRead : 0];

    if (recvBuffer != null && !recvBuffer.IsDisposed)
    {
        if (bytesRead > 0)
        {
            recvBuffer.CopyTo(data, 0, bytesRead);

            //Do anything else you wish with read data here.
        }

        //Dispose buffer if it's larger than a specified threshold
        if (recvBuffer.Size > BUFFER_SIZE_DISPOSAL_THRESHOLD)
        {
            recvBuffer.Dispose();
        }
    }

    if (bytesRead <= 0) return;

    //Read/Expect more data
    if (recvBuffer == null || recvBuffer.IsDisposed)
    {
        //Get new receive buffer if it is not available.
        recvBuffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE);
    }
    else if (recvBuffer.Size < RECEIVE_BUFFER_SIZE)
    {
        //If the receive buffer size is smaller than desired buffer size,
        //dispose receive buffer and acquire a new one that is long enough.
        recvBuffer.Dispose();
        recvBuffer = pool.GetBuffer(RECEIVE_BUFFER_SIZE);
    }

    socket.BeginReceive(recvBuffer.GetSegments(), SocketFlags.None, ReadCallback, stateObject);

}

If using the pattern presented above, it’s important to remember to dispose the buffer when closing the socket.
You must explicitly dispose the buffer. It does not define a finalizer, so once a buffer is created, it stays allocated until explicitly disposed.

CONCLUSION

The BufferPool project is the first sub-project of the ServerToolkit project. It is an efficient buffer manager for .NET socket operations.
It is written in C# 2.0 and targets .NET 2.0 for maximum backward compatibility.

BufferPool is designed with high performance and dependability in mind. Its goal is to abstract away the complexities of buffer pooling in a concurrent environment, so that the developer can focus on other issues and not worry about heap fragmentation caused by socket operations.

Exploring System.Void Part II

In my previous post, I described the role of System.Void in the .NET framework and demonstrated some of the restrictions placed on the type.
In this post, I’ll postulate why those restrictions are in place and I’ll try to bypass them in an attempt to create an instance of the type.

The restrictions on the System.Void type are documented in the Common Language Infrastructure (CLI) specification (ECMA-335)PDF Document.
I find two of these restrictions particularly interesting:

“The type System.Void is never boxable.” (Section 8.2.4)
“No location or value shall have System.Void” (Section 8.7)

Why is instantiation of the System.Void type forbidden? After all, as long as methods are not allowed to declare a return type of System.Void, the purpose of the type as discussed in my previous post remains intact, regardless of whether instances are allowed to exist or not.

So, what’s the harm in permitting instances of this type to exist? I proffer the following explanations.

Firstly, from a philosophical standpoint, it doesn’t make much sense to have the ability to instantiate a type that methods cannot declare as a return type, because that is effectively saying that you can create this object but your methods cannot pass its value (unless in a boxed representation or masqueraded as an inherited type) around.

Secondly, some unexpected issues can arise when calling methods declared in generic types. For example, if developers can instantiate System.Void, they’ll expect to be able to compile and run the following code, but by so doing produce a method that has a System.Void return type.

class Program
{
	static void Main(string[] args)
	{
		var instance = new MyClass<System.Void>().GetInstance();			
	}
	
}

class MyClass<T> where T:new()
{
	public T GetInstance()
	{
		return new T();
	}
}

The compiler/runtime can be updated to prevent such code from compiling or running, however it’s cleaner to have a rule that states that System.Void cannot be instantiated and that the expression “System.Void” is illegal anywhere in C#.

The last explanation I proffer has to do with pointers in C#, and I think it is the most functional explanation.
You can get the System.Type object of a value type pointer with the following expression:

typeof(MyStruct*)
For example:
typeof(int*)
evaluates to a System.Type object called System.Int32*

Similarly, typeof(bool*), typeof(DateTime*), typeof(char*) and typeof(System.Guid*) will evaluate to System.Type objects called System.Boolean*, System.DateTime*, System.Char* and System.Guid* respectively.

Now, there is a special kind of pointer called the void pointer which can point to any pointer type.
The type declaration for a void pointer is void*, and the following expression gets the System.Type object of a void pointer:

typeof(void*)
It evaluates to a System.Type object called System.Void*

You can already see how an ambiguity is introduced if instances of System.Void were allowed to exist.
In that scenario, typeof(System.Void*) would evaluate to a System.Type object also called System.Void*.
It would be impossible (or at least error-prone) to tell if the object is for a pointer to System.Void or for the special void pointer.

Nevertheless, and in spite of my failed attempts to instantiate System.Void in the previous post, it is possible to create an instance of System.Void -- by making it a static field.

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {60F1E74C-3123-4EF0-8269-A0C3B8B85ADF}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00670000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       1 (0x1)
    .maxstack  8
    IL_0000:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code listing above is equivalent to the following C# program (if it were possible to compile)

class Program
{
	public static System.Void o;
	static void Main()
	{
	}
}

If I compile the IL code using ilasm and run it, I don’t observe any errors, unlike in my previous attempts.
What does this mean? Did it create an instance of the type? Is the runtime skipping over that System.Void field creation instruction? Is the program dying silently?

This is a good example of the "If a tree falls in a forest and no one is around to hear it, does it make a sound?" philosophical riddle.

What I need is some observability. I need to be absolutely sure that the type was instantiated (or not).

I’ll just modify the code a little bit to get some output:

class Program
{
	public static System.Void o;
	static void Main()
	{
		Console.WriteLine(o.ToString());

	}
}

which translates to the following IL code:

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {EE60F7FD-BD3D-46C8-B353-A459F5119496}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00260000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       22 (0x16)
    .maxstack  8
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  constrained. [mscorlib]System.Void
    IL_000b:  callvirt   instance string [mscorlib]System.Object::ToString()
    IL_0010:  call       void [mscorlib]System.Console::WriteLine(string)
    IL_0015:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

If I run the program, I get a fatal InvalidProgramException error message. The issue is that ToString() is defined on the base System.Object class. When I call System.Void.ToString(), the runtime boxes the value type to an object before calling the ToString() method.
Remember that rule which states that System.Void cannot be boxed. It is enforced by the runtime. There is a check that the value is not System.Void during boxing, and if the check fails, the program is halted.

On a side note, this is another good reason to avoid boxing whenever possible. There is some overhead, besides copying the value to the boxed representation, due to many type checks.

System.Void does not define any members that we can access. The other members (GetType(), ToString(), GetHashCode(), etc.) are all inherited. Calling the inherited methods will lead to boxing which is prohibited. How can we observe its existence?

There’s one way.

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly MultiVoid
{
  .permissionset reqmin
             = {[mscorlib]System.Security.Permissions.SecurityPermissionAttribute = {property bool 'SkipVerification' = bool(true)}}
  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module MultiVoid.exe
// MVID: {AC411515-B789-4594-B52B-1EC2668D16C9}
.custom instance void [mscorlib]System.Security.UnverifiableCodeAttribute::.ctor() = ( 01 00 00 00 ) 
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00BC0000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .field public static valuetype [mscorlib]System.Void p
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       35 (0x23)
    .maxstack  1
    .locals init (valuetype [mscorlib]System.Void& pinned V_0,
             valuetype [mscorlib]System.Void& pinned V_1)
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  stloc.0
    IL_0006:  ldloc.0
    IL_0007:  conv.i
    IL_0008:  conv.i4
    IL_0009:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_000e:  ldc.i4.0
    IL_000f:  conv.u
    IL_0010:  stloc.0
    IL_0011:  ldsflda    valuetype [mscorlib]System.Void Program::p
    IL_0016:  stloc.1
    IL_0017:  ldloc.1
    IL_0018:  conv.i
    IL_0019:  conv.i4
    IL_001a:  call       void [mscorlib]System.Console::WriteLine(int32)
    IL_001f:  ldc.i4.0
    IL_0020:  conv.u
    IL_0021:  stloc.1
    IL_0022:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code above translates to the following uncompilable C# code:

class Program
{
	public static System.Void o;
	public static System.Void p;
	static void Main()
	{
		unsafe
		{

			fixed (System.Void* i = &o)
			{
				Console.WriteLine((int)i);
			}

			fixed (System.Void* j = &p)
			{
				Console.WriteLine((int)j);
			}

		}

	}
}

It displays the addresses of the System.Void instances in memory: If you run the IL code, you’ll see an output with the memory addresses of the two instances like as shown below:

Congratulations! You just created two instances of the forbidden System.Void type!

That may be as far as you may go. The runtime will detect attempts to place the instance on the evaluation stack, which is necessary to return the instance value from a method.

Exploring System.Void Part I

When calling a method in a dynamically created instance of a type that is discovered at runtime, it's useful to discover the types of the method parameters and the method return type. This information is needed to successfully call the method and retrieve its return value.

It's also useful to discover if the method doesn't have a return type, so that we know not to expect a return value.
One way to find out is to check if the MethodBase.Invoke call returns a null, since a dynamically invoked method that has no return type will return a null. However, this is not the best approach for the following reasons.

Firstly, any method that returns a reference type can return a null, rendering such null checks unreliable.

Secondly, this approach cannot be used to determine the return type before invoking the method.

Fortunately, MethodInfo objects have a ReturnType property that developers can inspect to determine the return type before invoking the method. For instance, if the method returns a string type, MethodInfo.ReturnType will evaluate to typeof(string). It would seem that the natural way to determine if a method does not define a return type would be to check if MethodInfo.ReturnType == typeof(null), however, that won't work because the expression typeof(null) is illegal in C#. Null is not a type.

What's needed is a specially marked type that can be used in the typeof() evaluation to determine that the method does not have a return type. Think about that for a few seconds to get a feel of how counter-intuitive that sounds.
The issue with this approach is that if a method returns an instance of the proposed special type, then the test becomes inconclusive and unreliable. To prevent this from happening, the runtime must bar creation of methods that return this special type.

Enter the System.Void structure. This type is specially designated by .NET for just this purpose. In C#, the void keyword is an alias for the System.Void structure, thus MethodInfo.ReturnType == typeof(void) is a reliable means of discovering if a method has a return type. As expected, no method is allowed to define System.Void as its return type.

This solution looks good and seems like a perfect answer to the "no return type detection" problem. However, there may be a lot more involved. C# and the CLR strangely takes it one step further by disallowing instantiation of the System.Void type by any means. Allow me to demonstrate:

Attempt 1: Try to instantiate System.Void normally

static void Main()
{
    object o = new System.Void();
    //object o = new void() is illegal in C# lingo
}
You'll get a "System.Void cannot be used from C# -- use typeof(void) to get the void type object" (CS0673) error message if you try to compile the code.

Attempt 2: Try to instantiate System.Void dynamically

static void Main(string[] args)
{

    object o = Activator.CreateInstance(typeof(void));
            
}	
It compiles, but when you try to run it, you get a "Cannot dynamically create an instance of System.Void." error message.

Attempt 3: Bypass the C# compiler, Try to create it directly from IL

// Metadata version: v2.0.50727
.assembly extern mscorlib
{
  .publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
  .ver 2:0:0:0
}
.assembly ConsoleApplication1
{

  .hash algorithm 0x00008004
  .ver 1:0:0:0
}
.module ConsoleApplication1.exe
// MVID: {47CAF74F-C24A-400E-A0F9-26EB27500120}
.imagebase 0x00400000
.file alignment 0x00000200
.stackreserve 0x00100000
.subsystem 0x0003       // WINDOWS_CUI
.corflags 0x00000001    //  ILONLY
// Image base: 0x00D10000


// =============== CLASS MEMBERS DECLARATION ===================

.class private auto ansi beforefieldinit Program
       extends [mscorlib]System.Object
{
  .field public static valuetype [mscorlib]System.Void o
  .method private hidebysig static void  Main() cil managed
  {
    .entrypoint
    // Code size       12 (0xc)
    .maxstack  8
    IL_0000:  ldsflda    valuetype [mscorlib]System.Void Program::o
    IL_0005:  initobj    [mscorlib]System.Void
    IL_000b:  ret
  } // end of method Program::Main

  .method public hidebysig specialname rtspecialname 
          instance void  .ctor() cil managed
  {
    // Code size       7 (0x7)
    .maxstack  8
    IL_0000:  ldarg.0
    IL_0001:  call       instance void [mscorlib]System.Object::.ctor()
    IL_0006:  ret
  } // end of method Program::.ctor

} // end of class Program

The IL code above is equivalent to the following C# code
using System;

class Program
{
	public static System.Void o;
	static void Main()
	{
		o = new System.Void();
	}
}
If you compile the IL code with ilasm, It compiles successfully, however it fails verification when you run Peverify against the compiled assembly. If you try to run the assembly, it runs into a fatal InvalidProgramException exception.
If you replace occurrences of System.Void in the IL code to any other struct in the System namespace (besides the ones that map to simple types -- they have a different syntax in IL), the IL code will compile and run smoothly.

From the examples shown above, we have established that the C# compiler and runtime prevents instantiation of the System.Void type. In my next post, We'll explore the System.Void type some more and try to figure out why the runtime doesn't want it to exist.

Happy new year!!

A Simple ASP.NET State Server Failover Scheme

Introduction

A common question that comes up when setting up a web application to use the state server is “what happens if the state server fails?” and the answer is that the web application fails.
This article proposes a failover solution, such that if one state server goes down, the web application switches to another one. In addition, the solution performs state server load balancing by distributing requests across available state servers.

Overview

The proposed failover system monitors a specified list of state servers to determine which ones are running; the web application can then decide on which one to use. The process of monitoring a state server is expensive, so it is handled by a dedicated external service. This service notifies the web application (and other web applications) when state servers come online or go offline. The process is illustrated below.

How it works

The failover system comprises two parts.

The first part is the monitoring service, which polls the status of a given list of servers by simply connecting and disconnecting to the servers continuously. If there are any changes in the availability of servers, for instance, a server that was previously unavailable becomes available or vice versa; one or more status files are updated to reflect the change. A status file contains information about the state servers in use and their online status. ASP.NET applications can detect changes to these status files and react accordingly.

The monitoring service has a configurable time period, within which a monitored server that comes online must stay online before the service will update the status files with the change in status for that server. This helps reduce connections to servers that are successively coming online and going offline -- the so called flapping server phenomenon. The length of this time period is determined by the ServerWarmUpTime configuration setting.
It's important to note that the monitoring service can detect the availability of other types of servers, not just ASP.NET state servers, and so can be used for other purposes.

The second part consists of configuration settings and code in the web application that expands upon Maarten Balliauw's most excellent series on state server partitioning and load balancing. The web application is configured such that the configuration file is extended to the external status file. Changes made to the status file cause the application configuration settings to be re-read and updated with the new values. Thus, the web application always has the latest server availability information and uses the information to distribute requests to available state servers -- achieving both load balancing and failover support.

For example, if there are five state servers in use and they are all running, the status file will indicate that the five servers are available; the web application then distributes state server requests evenly across the five servers. If two of the state servers were to suddenly go down, the status file will be updated to indicate that only three state servers are available; the web application then redistributes state server requests to only those three. The overall effect is that during a state server downtime, users will be able to continue using the application. Some sessions will be lost, but that is a slight annoyance compared to the entire application going down for a long period of time.

To use this load-balanced, failover-supported setup, the web application needs a few configuration changes and two code files in the App_Code folder; namely ServerListSectionHandler.cs and PartitionResolver.cs. ServerListSectionHandler.cs enables the status file to be read as part of the application configuration. PartitionResolver.cs contains a custom state server partition resolver class that decides which state server to connect to. This class also tries to pin users to particular state servers so that changes in the status file only affects users whose session was stored on the failing server.

Using the code

To set up the server monitoring service

  1. Download the source files.
    You can download the source code at http://www.codeproject.com/KB/aspnet/stateserverfailover.aspx


  2. Open up the ServerMonitor solution in visual studio.

    The solution contains two projects. One runs the service as a console application and the other one runs it as a windows service. The ServerMonitorService project compiles as a windows service and can be installed and uninstalled with the included install_service.bat and uninstall_service.bat files. The ConsoleServerMonitor project runs the service as a console application, which is a lot easier to test and debug. Both projects share the same sources and function identically.

  3. Open up the project's application configuration file.

  4. In the Servers section, specify the state servers you want to use, like as shown below:

    <Servers>
        <!-- List of servers to poll -->
        <add key="Server1"  value="localhost:42424" />
        <add key="Server2"  value="appserver1:42424" />
        <add key="Server3"  value="72.27.255.9:42424" />    
    </Servers>
     

  5. In the StatusFilePaths section, add the full file pathname of the status file.
    This file should be located in the folder containing your web application or in subfolders.

    You can add multiple paths, if you want to notify multiple web applications, as shown below:

    <StatusFilePaths>
        <!-- List of file paths where status files are saved/updated -->
        <add key="Web1" value="C:\Inetpub\wwwroot\MyWeb1\server_status.config.xml"/>    
        <add key="Web2" value="C:\Inetpub\wwwroot\SuperWeb2\server_status.config.xml"/>        
    </StatusFilePaths>
      

  6. Build the project.

  7. If you built the ServerMonitorService project, navigate to the output folder and run install_service.bat to install the service.

  8. If you built and installed the windows service, you can start Server Monitoring Service in the Services list. If you built the console server, run ConsoleServerMonitor.exe or simply start debugging from Visual Studio.

  9. Note that the status files are created in the specified folders.

To configure your web application

  1. Open your web application in visual studio

  2. Add an App_Code ASP.NET folder to your application, if your application does not have one.

  3. Copy PartitionResolver.cs and ServerListSectionHandler.cs from SampleWeb\App_Code folder to your web application's App_Code folder.

  4. Open the project's web configuration file. (Add a new web configuration file if your application does not have one)

  5. Add a new SessionStateServers section element in the configSections collection as shown below:

    <configSections>
    	<section name="SessionStateServers" type="ServerListSectionHandler" restartOnExternalChanges="false"/>
    </configSections>
    

  6. Configure the newly added SessionStateServers section to be read from an external file as shown below:
    <SessionStateServers configSource="server_status.config.xml"/>
    
    
    (If the status file has a different filename, specify that instead)

  7. In the system.web element, configure the application to use the custom partition resolver as shown below:
    <system.web>    
        <sessionState mode="StateServer" partitionResolverType="PartitionResolver"/>
    ...
    
    

  8. Your web application is now set up to use the state server failover system

Points of Interest

I originally wanted the monitoring service to update a single status file, which multiple web applications could share. That plan didn't work because ASP.NET only works with external configuration files that are located in the application folder or in its subfolders. Because of this restriction, different web applications can not share one external configuration file.

It's not necessary to set the restartOnExternalChanges attribute of the section element in the web.config file to true. Setting this attribute to true causes the web application to restart whenever the external config file is updated, which will cause any data stored in the Application object to be lost.
The web application will still read the latest data in the external config file, if the attribute's value is set to false, without restarting the application.

The name of the root element of the status file is determined by the StatusXMLRootTag setting of the monitoring service's configuration.
The name must match the name of the new section you add to your web application's web.config file. The name must also be specified in the state server partition resolver class (PartitionResolver.cs)