我有一个控制台应用程序,它从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);
}
有任何帮助吗?为什么它不能在一个连续的循环中工作
答案 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
的任何更深奥的行为