我有一个任务outputTask
。该任务读取StreamReader
(带StreamReader.ReadLineAsync()
),
它只能以这种方式运作:
var outputTask = plinkInstance.StandardOutput.ReadLineAsync().ContinueWith(hasOutputReaded);
Action<Task<string>> hasOutputReaded = null;
hasOutputReaded = (previousTask) =>
{
resetTimer.Invoke();
_outputLines.Add(previousTask.Result);
previousTask = plinkInstance.StandardOutput.ReadLineAsync();
previousTask.ContinueWith(hasOutputReaded);
};
它的作用是肯定的,但还有另一种方法可以让它变得更好吗?
修改:现在看起来就是这样
// ...
Task.Factory.StartNew(() => readUntilEnd(plinkInstance.StandardOutput, timer, cancel.Token), cancel.Token);
// ...
方法
private static void readUntilEnd(StreamReader stream, System.Timers.Timer timer, CancellationToken canelToken)
{
char[] buffer = new char[1];
stream.ReadAsync(buffer, 0, 1);
int cooldown = 0;
while (!canelToken.IsCancellationRequested)
{
if (buffer[0] != '\0')
{
readAChar(buffer[0]);
buffer[0] = '\0';
stream.ReadAsync(buffer, 0, 1);
timer.Stop();
timer.Start();
cooldown = 0;
}
else
{
if (cooldown < 100)
cooldown++;
}
if (cooldown > 0)
Thread.Sleep(cooldown);
}
}
为什么我需要CancellationToken
?我也可以传递一个bool-object?
答案 0 :(得分:2)
由于您以异步方式运行连续任务,为什么不让它成为无限循环呢?
Task.Run(() =>
{
while (true)
{
var output = await READ_LINE_ASYNCHRONOUSLY();
_outputLines.Add(output);
}
});
如果你需要一些方法来摆脱你的循环(我假设你可能),请使用CancellationToken
,例如,这里:
How to cancel a Task in await?
编辑:这里有完整的代码,你可能想做什么:
Task.Run(() => ReadUntilEnd(streamReader, cancellationTokenSource.Token),
cancellationTokenSource.Token);
//...
private static async Task ReadUntilEnd(StreamReader streamReader,
CancellationToken cancellationToken)
{
char[] buffer = new char[1];
while (!cancellationToken.IsCancellationRequested)
{
await streamReader.ReadAsync(buffer, 0, 1);
readAChar(buffer[0]);
}
}
答案 1 :(得分:0)
private static async Task readUntilEnd(StreamReader stream, System.Timers.Timer timer, CancellationToken canelToken)
{
char[] buffer = new char[1];
Task readTask = stream.ReadAsync(buffer, 0, 1);
int cooldown = 5;
while (!canelToken.IsCancellationRequested)
{
if (readTask.IsCompleted)
{
readAChar(buffer[0]);
buffer[0] = '\0';
readTask = stream.ReadAsync(buffer, 0, 1);
timer.Stop();
timer.Start();
cooldown = 0;
}
else
{
if (cooldown < 100)
cooldown++;
}
if (cooldown > 0)
await Task.Delay(cooldown, canelToken);
}
}