Alex Rivera | Logout

Is a non-blocking, single-threaded, asynchronous web server (like Node.js) possible in .NET?

Asked 2012-01-18T06:03:15.260
56

I was looking at this question, looking for a way to create a single-threaded, event-based nonblocking asynchronous web server in .NET.

This answer looked promising at first, by claiming that the body of the code runs in a single thread.

However, I tested this in C#:

using System;
using System.IO;
using System.Threading;

class Program
{
    static void Main()
    {
        Console.WriteLine(Thread.CurrentThread.ManagedThreadId);

        var sc = new SynchronizationContext();
        SynchronizationContext.SetSynchronizationContext(sc);
        {
            var path = Environment.ExpandEnvironmentVariables(
                @"%SystemRoot%\Notepad.exe");
            var fs = new FileStream(path, FileMode.Open,
                FileAccess.Read, FileShare.ReadWrite, 1024 * 4, true);
            var bytes = new byte[1024];
            fs.BeginRead(bytes, 0, bytes.Length, ar =>
            {
                sc.Post(dummy =>
                {
                    var res = fs.EndRead(ar);

                    // Are we in the same thread?
                    Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
                }, null);
            }, null);
        }
        Thread.Sleep(100);
    }
}

And the result was:

1
5

So it seems like, contrary to the answer, the thread initiating the read and the thread ending the read are not the same.

So now my question is, how do you to achieve a single-threaded, event-based nonblocking asynchronous web server in .NET?

Edit
Report

2 Answers

0

First about SynchronizationContext. It's just like Sam wrote. Base class won't give You single-thread functionality. You probably got that idea from WindowsFormsSynchronizationContext which provides functionality to execute code on UI thread.

You can read more here

I've written a piece of code that works with ThreadPool parameters. (Again something Sam already pointed out).

This code registers 3 asynchronous actions to be executed on free thread. They run in parallel until one of them changes ThreadPool parameters. Then each action is executed on the same thread.

It only proves that you can force .net app to use one thread. Real implementation of web server that would receive and process calls on only one thread is something entirely different :).

Here's the code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.IO;

namespace SingleThreadTest
{
    class Program
    {
        class TestState
        {
            internal string ID { get; set; }
            internal int Count { get; set; }
            internal int ChangeCount { get; set; }
        }

        static ManualResetEvent s_event = new ManualResetEvent(false);

        static void Main(string[] args)
        {
            Console.WriteLine(Thread.CurrentThread.ManagedThreadId);
            int nWorkerThreads;
            int nCompletionPortThreads;
            ThreadPool.GetMaxThreads(out nWorkerThreads, out nCompletionPortThreads);
            Console.WriteLine(String.Format("Max Workers: {0} Ports: {1}",nWorkerThreads,nCompletionPortThreads));
            ThreadPool.GetMinThreads(out nWorkerThreads, out nCompletionPortThreads);
            Console.WriteLine(String.Format("Min Workers: {0} Ports: {1}",nWorkerThreads,nCompletionPortThreads));
            Thread
answered 2012-01-26T17:53:43.537
-2

you can this framework SignalR and this Blog about it

answered 2012-01-18T06:30:14.610

Your Answer