Task.Factory.StartNew无法在控制台c#应用程序中运行

时间:2014-11-04 06:30:38

标签: c# .net console-application

我有一个控制台应用程序,它从Console.OpenStandardInput()读取消息; 我在一项任务中这样做。但似乎没有用。

   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();
}

这是我的OpenStandardStreamIn函数

   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);
            }

有任何帮助吗?为什么它不能在一个连续的循环中工作

1 个答案:

答案 0 :(得分:3)

你基本上在Console.ReadLine和你的任务之间有竞争条件。他们两个都试图从标准输入读取 - 我当然不知道在同时读取两个线程的标准输入时你应该期待什么,但它似乎值得避免。

您可以通过将任务更改为 other 而不是从标准输入读取来轻松地对此进行测试。例如:

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();
    }
}

如果您的真实代码需要从标准输入中读取,那么我建议您将Console.ReadLine()更改为readInputStream.Wait()。如果您使用的是.NET 4.5,我建议您使用Task.Run代替Task.Factory.StartNew(),只是为了提高可读性 - 假设您不需要TaskFactory.StartNew的任何更深奥的行为