I am new with async task in C# 4.5 and feel insecure about this:I want to create a Windows Service that listen messages from a network (similar to msmq for example), when a message is received, do stuff not CPU bound (call webservices and rest API) without blocking other messages.I created this console application in order to test the concept:using System;using System.Collections.Generic;using System.Linq;using System.Threading;using System.Threading.Tasks;namespace Sandbox{    public class Program    {        static CancellationTokenSource cts;        static CancellationToken ct;        static TaskCompletionSource<bool> maintask;        static void Main(string[] args)        {            Console.WriteLine(string.Format([{0:000}] Start., Thread.CurrentThread.ManagedThreadId));            cts = new CancellationTokenSource();            ct = cts.Token;            // Run inside a new thread, the service will have 3 dedicated threads            maintask = new TaskCompletionSource<bool>(                Task.Factory.StartNew(() =>                {                    Run(ct);                    maintask.SetResult(true);                },                TaskCreationOptions.LongRunning));            Console.WriteLine(Press a key to stop.);            Console.ReadKey();            cts.Cancel();         // Stop the main threads            maintask.Task.Wait(); // Wait for tasks to end properly        }        static List<Task> tasks;        /// <summary>Main loop</summary>        static void Run(CancellationToken cancel)        {            Console.WriteLine(string.Format([{0:000}] Start loop., Thread.CurrentThread.ManagedThreadId));            tasks = new List<Task>();            int iteration = 0;            while (!ct.IsCancellationRequested)            {                string onemsg = WaitMessageFromNetwork();                // for the test, randomize duration of async task.                iteration += 100;                 int wait;                switch (iteration)                {                    case 200: wait = 1000; break;                    case 300: wait = 2000; break;                    case 400: wait = 1500; break;                    case 500: wait = 1600; break;                    case 600: wait = 1100; break;                    case 700: wait = 1200; break;                    case 800: wait = 1900; break;                    case 900: wait = 1800; break;                    case 1000: wait = 800; break;                    case 1100: wait = 900; break;                    default: wait=0; break;                }                if (wait > 0) tasks.Add(DoWorkAsync(wait, onemsg));                foreach (Task t in tasks.Where(x => x.IsFaulted))                {                    Console.WriteLine(t.Exception); // log.error(...                }                tasks.RemoveAll(x => x.IsCanceled | x.IsCompleted | x.IsFaulted); // Remove finished tasks                // Limit asynchronism to 5 tasks for the test, unnecessary ? X in real service ?                if (tasks.Count > 4) Console.WriteLine(WaitAny returns {0}., Task.WaitAny(tasks.ToArray()));            }            Task.WaitAll(tasks.ToArray()); // If the service stop, wait pending tasks to finish.        }        static string WaitMessageFromNetwork()        {            Thread.Sleep(100); // Real method will not block the thread            return dummy;        }        /// <summary>Do I/O bound stuff : call WebServices async and REST API.</summary>        static async Task DoWorkAsync(int wait, string onemsg)        {            try            {                Console.WriteLine(string.Format([{0:000}] START {1:0000}., Thread.CurrentThread.ManagedThreadId, wait));                await Task.Delay(wait);                Console.WriteLine(string.Format([{0:000}] END   {1:0000}., Thread.CurrentThread.ManagedThreadId, wait));            }            catch(Exception ex)            {                Console.WriteLine(ex); // log.error(...            }        }    }}It works but is it OK to do like this?In my tests, START and END messages are not one the same thread (not a problem in my case), its normal if I understand because a console or service application does not have a SynchronizationContext ?
Windows Service listening for messages from a network
c#;async await
It looks like a good start.  The main thing I would look at is if you really need your tasks list.  Right now it gives you 2 things: a way to find out about failures, and a way to count active tasks.  You should be able to set up exception failures for each task, and you might not need to limit the number of active tasks, depending on your specific concerns.Your comment in WaitMessageFromNetwork indicates that it won't block the thread, but that doesn't seem possible with your current setup.  You can make the read asynchronous, but that would require changes to the Run loop.  This highlights another reason to change from the list-centric error reporting - you only find out about errors when a new command comes in from the network.