当流关闭时退出while循环?

时间:2010-01-17 11:43:44

标签: c# file-io stream

这是网络流问题,但我将测试用例简化为控制台输入: 我开始了一个线程,等待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");
    }
  }
}

3 个答案:

答案 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");
    }
}