Domanda

Voglio eseguire un'attività in background che legge l'input da un TextReader e lo elabora una riga alla volta. Voglio che l'attività in background si blocchi fino a quando l'utente digita del testo in un campo e fa clic sul pulsante di invio. C'è un po 'di sapore di TextReader che si bloccherà fino a quando il testo non sarà disponibile e ti permetterà in qualche modo di aggiungere altro testo alla fonte sottostante?

Ho pensato che uno StreamReader e StreamWriter che puntavano allo stesso MemoryStream potrebbero funzionare, ma non sembra. StreamReader rileva che MemoryStream è vuoto all'inizio e non verifica mai più.

Mi rendo conto che sarebbe più semplice scrivere un metodo ProcessLine () e chiamarlo ogni volta che l'utente fa clic sul pulsante di invio. Tuttavia, sto cercando di progettare un'architettura plug-in e vorrei che i plug-in sembrassero come app console vecchio stile con un flusso di input e un flusso di output. Voglio che il flusso di input del plug-in si blocchi solo finché l'utente non fa clic sul pulsante di invio con del testo di input.

È stato utile?

Soluzione

Sembra che non ci sia alcuna implementazione di questo - il che è strano, dal momento che sono d'accordo che sarebbe un costrutto utile. Ma dovrebbe essere semplice da scrivere. Qualcosa del genere dovrebbe funzionare:

  public class BlockingStream: Stream
  {
    private readonly Stream _stream;

    public BlockingStream(Stream stream)
    {
      if(!stream.CanSeek)
        throw new ArgumentException("Stream must support seek", "stream");
      _stream = stream;
    }

    public override void Flush()
    {
      lock (_stream)
      {
        _stream.Flush();
        Monitor.Pulse(_stream);
      }
    }

    public override long Seek(long offset, SeekOrigin origin)
    {
      lock (_stream)
      {
        long res = _stream.Seek(offset, origin);
        Monitor.Pulse(_stream);
        return res;
      }
    }

    public override void SetLength(long value)
    {
      lock (_stream)
      {
        _stream.SetLength(value);
        Monitor.Pulse(_stream);
      }
    }

    public override int Read(byte[] buffer, int offset, int count)
    {
      lock (_stream)
      {
        do
        {
          int read = _stream.Read(buffer, offset, count);
          if (read > 0)
            return read;
          Monitor.Wait(_stream);
        } while (true);
      }
    }

    public override void Write(byte[] buffer, int offset, int count)
    {
      lock (_stream)
      {
        long currentPosition = _stream.Position;
        _stream.Position = _stream.Length;
        _stream.Write(buffer, offset, count);
        _stream.Position = currentPosition;
        Monitor.Pulse(_stream);
      }
    }

    public override bool CanRead
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanRead;
        }
      }
    }

    public override bool CanSeek
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanSeek;
        }
      }
    }

    public override bool CanWrite
    {
      get
      {
        lock (_stream)
        {
          return _stream.CanWrite;
        }
      }
    }

    public override long Length
    {
      get
      {
        lock (_stream)
        {
          return _stream.Length;
        }
      }
    }

    public override long Position
    {
      get
      {
        lock (_stream)
        {
          return _stream.Position;
        }
      }
      set
      {
        lock (_stream)
        {
          _stream.Position = value;
          Monitor.Pulse(_stream);
        }
      }
    }
  }

Altri suggerimenti

Penso che sarebbe molto meglio creare un evento nella tua applicazione principale che viene generato quando l'utente preme Invia. I dati di testo sarebbero passati negli argomenti dell'evento. Ogni plug-in registra un gestore eventi per l'evento e gestisce i dati trasmessi quando viene generato l'evento. Ciò consente a molti plug-in di elaborare i dati da un singolo invio senza molto lavoro idraulico da parte tua e significa che i plug-in sono in grado di rimanere inattivi fino a quando non viene generato l'evento.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top