C# 当流关闭时退出while循环?
这是一个网络流问题,但我将测试用例简化为控制台输入: 我启动了一个线程,ehich等待2秒钟,然后关闭流读取器。但之后 关闭流/流读取器。而循环仍在等待sr.ReadLine()方法。 我不想在关闭流/流读取器时使其自动退出循环 我还尝试了流阅读器的线程安全版本;TextReader.synchronized。 但结果是一样的C# 当流关闭时退出while循环?,c#,file-io,stream,C#,File Io,Stream,这是一个网络流问题,但我将测试用例简化为控制台输入: 我启动了一个线程,ehich等待2秒钟,然后关闭流读取器。但之后 关闭流/流读取器。而循环仍在等待sr.ReadLine()方法。 我不想在关闭流/流读取器时使其自动退出循环 我还尝试了流阅读器的线程安全版本;TextReader.synchronized。 但结果是一样的 using System; using System.IO; using System.Threading; namespace StreamReaderTest {
using System;
using System.IO;
using System.Threading;
namespace StreamReaderTest {
class Program {
static void Main(string[] args) {
new Program();
}
private StreamReader sr;
public Program() {
sr = new StreamReader(Console.OpenStandardInput());
new Thread(new ThreadStart(this.Close)).Start(); ;
string line;
while ((line = sr.ReadLine()) != null) {
Console.WriteLine(line);
}
}
public void Close() {
Thread.Sleep(2000);
sr.Close();
Console.WriteLine("Stream Closed");
}
}
}
将流操作封装在一个类中,以便您可以轻松地同步这些方法,使它们具有线程安全性,并使读线注意到关闭状态:
using System;
using System.IO;
using System.Threading;
namespace StreamReaderTest {
class SynchronizedReader {
private StreamReader _reader;
private object _sync;
public SynchronizedReader(Stream s) {
_reader = new StreamReader(s);
_sync = new object();
}
public string ReadLine() {
lock (_sync) {
if (_reader == null) return null;
return _reader.ReadLine();
}
}
public void Close() {
lock (_sync) {
_reader.Close();
_reader = null;
}
}
}
class Program {
static void Main(string[] args) {
new Program();
}
private SynchronizedReader reader;
public Program() {
reader = new SynchronizedReader(Console.OpenStandardInput());
new Thread(new ThreadStart(this.Close)).Start();
string line;
while ((line = reader.ReadLine()) != null) {
Console.WriteLine(line);
}
}
public void Close() {
Thread.Sleep(2000);
reader.Close();
Console.WriteLine("Stream Closed");
}
}
}
为了防止ReadLine方法在等待一个完整的行时发生阻塞,您可能希望一次从流中读取一个字符。请注意,您必须检查读取字符的循环内的关闭状态:
class SynchronizedReader {
private Stream _stream;
private object _sync;
public SynchronizedReader(Stream s) {
_stream = s;
_sync = new object();
}
public string ReadLine() {
lock (_sync) {
StringBuilder line = new StringBuilder();
while (true) {
if (_stream == null) return null;
int c = _stream.ReadByte();
switch (c) {
case 10: break;
case 13:
case -1: return line.ToString();
default: line.Append((char)c);
}
}
}
}
public void Close() {
lock (_sync) {
_stream.Close();
_stream = null;
}
}
}
这对你有用吗
class Program
{
static void Main(string[] args)
{
new Program();
}
private StreamReader sr;
private bool forcefullyClose = false;
public Program()
{
new Thread(new ThreadStart(this.Close)).Start(); ;
using (sr = new StreamReader(Console.OpenStandardInput()))
{
string line;
while (!forcefullyClose && (line = sr.ReadLine()) != null)
{
Console.WriteLine(line);
}
}
}
public void Close()
{
Thread.Sleep(5000);
forcefullyClose = true;
Console.WriteLine("Stream Closed");
}
}
在控制台示例中,您可以使用Peek检查角色是否可用。 对于网络流,您可以使用长度来检查是否有任何输入可用。
如果您不希望它被阻止,请不要在输入未挂起的情况下进行读取。相关:StreamReader不应该完全由您控制吗?也许这个例子有点误导,在网络流的情况下,我希望它已经起作用了;我怀疑关闭当前进程自己的输入流的微妙之处可能会让这里的事情变得混乱?是的,它完全在我的控制之下。我可以关闭或处置,但正如我所写的那样,无法在有/无异常的情况下自动退出for循环。它等待额外的读取。您是否尝试过NetworkStream.ReadTimeout之类的方法?是的,但读卡器仍在等待另一个“输入字符”。@Fırat:是的,如果行不完整,ReadLine方法可以阻止流。你必须一次读一个字符才能避免这种情况。@Fırat:你是如何实现的?我在上面加了一个例子。不,对不起。同样的情况。