Task.Factory.StartNew在控制台c#应用程序中不起作用

本文关键字:应用程序 不起作用 控制台 Factory StartNew Task | 更新日期: 2023-09-27 18:29:03

我有一个控制台应用程序,它从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);
            }

有什么帮助吗?为什么它不能在连续循环中工作

Task.Factory.StartNew在控制台c#应用程序中不起作用

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

您可以通过更改任务来做一些其他的事情,而不是从标准输入中读取,来轻松地测试这一点。例如:

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的任何更深奥的行为。