Task.Factory.StartNew is not working in console c# application

I am having a console application which reads the messages from Console.OpenStandardInput(); I am doing this in a task. but it seems to be not working.

   static void Main(string[] args)
        {
    wtoken = new CancellationTokenSource();
            readInputStream = Task.Factory.StartNew(() =>
            {
                wtoken.Token.ThrowIfCancellationRequested();
                while (true)
                { 
                    if (wtoken.Token.IsCancellationRequested)
                    {
                        wtoken.Token.ThrowIfCancellationRequested();
                    }
                    else
                    {
                       OpenStandardStreamIn();
                    }
                }
            }, wtoken.Token
            );
     Console.ReadLine();
}

Here is my OpenStandardStreamIn function

   public static void OpenStandardStreamIn()
        {
                Stream stdin = Console.OpenStandardInput();
                int length = 0;
                byte[] bytes = new byte[4];
                stdin.Read(bytes, 0, 4);
                length = System.BitConverter.ToInt32(bytes, 0);
                string input = "";
                for (int i = 0; i < length; i++)
                {
                    input += (char)stdin.ReadByte();
                }
                Console.Write(input);
            }

Any help? why it is not working in a continous loop

Jon Skeet
people
quotationmark

You basically have a race condition between Console.ReadLine and your task. Both of them are trying to read from standard input - and I certainly don't know what you should expect when reading from standard input from two threads at the same time, but it seems like something worth avoiding.

You can easily test this by changing the task to do something other than reading from standard input. For example:

using System;
using System.Threading;
using System.Threading.Tasks;

class Test
{
    static void Main()
    {
        var wtoken = new CancellationTokenSource();
        var readInputStream = Task.Factory.StartNew(() =>
        {
            for (int i = 0; i < 10; i++)
            {
                Console.WriteLine(i);
                Thread.Sleep(200);
            }
        }, wtoken.Token);
        Console.ReadLine();
    }
}

If your real code needs to read from standard input, then I suggest you change Console.ReadLine() into readInputStream.Wait(). I'd also suggest you use Task.Run instead of Task.Factory.StartNew() if you're using .NET 4.5, just for readability - assuming you don't need any of the more esoteric behaviour of TaskFactory.StartNew.

people

See more on this question at Stackoverflow