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);
}
有什么帮助吗?为什么它不能在连续循环中工作
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
的任何更深奥的行为。