这是网络流问题,但我将测试用例简化为控制台输入: 我开始了一个线程,等待2秒钟并关闭流阅读器。但是之后 关闭流/流阅读器。 while循环仍然等待sr.ReadLine()方法。 关闭流/流阅读器时,我不想自动退出循环。
我还尝试了Stream Reader的线程安全版本; TextReader.synchronized。 但结果是一样的。
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");
}
}
}
答案 0 :(得分:1)
在控制台示例中,您可以使用Peek检查角色是否可用。 对于网络流,您可以使用“长度”来检查是否有任何输入可用。 如果您不希望它被阻止,则永远不要在没有输入的情况下进行读取。
答案 1 :(得分:0)
将流操作封装在一个类中,这样您就可以轻松地同步这些方法以使它们成为线程安全的,并使ReadLine注意到处于关闭状态:
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;
}
}
}
答案 2 :(得分:0)
这对你有用吗?
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");
}
}