3

アプリケーションをコンソール アプリまたは Windows フォーム アプリとして実行できるという興味深いジレンマがあります。

私は自分のアプリケーション全体にこのような大量のコードを書きたくないので:

If ( IsConsoleApp() )
{
    // process Console input and output
}
else
{
    // process Windows input and output
}

これを防ぐために、TextReader と TextWriter インスタンスを渡すことができる 2 つのメソッドを作成し、その後これらを使用して入力と出力を処理することにしました。

public void SetOutputStream( TextWriter outputStream )
{
    _outputStream = outputStream;
}

public void SetInputStream( TextReader inputStream )
{
    _inputStream = inputStream;
}

// To use in a Console App:
SetOutputStream( Console.Out );
SetInputStream( Console.In );

コンソール ウィンドウにテキストを表示するには、次のようにするだけです。

_outputStream.WriteLine( "Hello, World!");

テキストは魔法のようにコンソールにリダイレクトされます。

さて、私の問題は、Windows アプリケーションで同様のことを行うにはどうすればよいかということです。_outputStream読み取り専用のテキスト ボックス コントロールを含むフォームを作成しましたが、その内容をこのテキスト ボックスにリアルタイムでリダイレクトしたいと考えています。

また、_inputStream別のテキスト ボックス コントロールのコンテンツを含めて、アプリがテキスト ボックスを直接ではなく、このストリームから読み取ることができるようにします。

前もって感謝します。

4

2 に答える 2

1

キューの内容を処理するためにバックアップを継承して使用するConcurrentStreamWriterクラスを作成することで、これを解決することができました。StreamWriterConcurrentQueueBackgroundWorker

これは私が思いついた解決策です:

using System;
using System.Collections.Concurrent;
using System.ComponentModel;
using System.IO;
using System.Threading;
using System.Windows.Forms;

namespace Quest.Core.IO
{
    public class ConcurrentStreamWriter : StreamWriter
    {
        private ConcurrentQueue<String> _stringQueue = new ConcurrentQueue<String>();
        private Boolean _disposing;
        private RichTextBox _textBox;

        public ConcurrentStreamWriter( Stream stream )
            : base( stream )
        {
            CreateQueueListener();
        }

        public ConcurrentStreamWriter( Stream stream, RichTextBox textBox )
            : this( stream )
        {
            _textBox = textBox;
        }

        public override void WriteLine()
        {
            base.WriteLine();
            _stringQueue.Enqueue( Environment.NewLine );
        }

        public override void WriteLine( string value )
        {
            base.WriteLine( value );
            _stringQueue.Enqueue( String.Format( "{0}\n", value ) );
        }

        public override void Write( string value )
        {
            base.Write( value );
            _stringQueue.Enqueue( value );
        }

        protected override void Dispose( bool disposing )
        {
            base.Dispose( disposing );

            _disposing = disposing;
        }

        private void CreateQueueListener()
        {
            var bw = new BackgroundWorker();

            bw.DoWork += ( sender, args ) =>
            {
                while ( !_disposing )
                {
                    if ( _stringQueue.Count > 0 )
                    {
                        string value = string.Empty;
                        if ( _stringQueue.TryDequeue( out value ) )
                        {
                            if ( _textBox != null )
                            {
                                if ( _textBox.InvokeRequired )
                                {
                                    _textBox.Invoke( new Action( () =>
                                    {
                                        _textBox.AppendText( value );
                                        _textBox.ScrollToCaret();
                                    } ) );
                                }
                                else
                                {
                                    _textBox.AppendText( value );
                                    _textBox.ScrollToCaret();
                                }
                            }
                        }
                    }
                }
            };

            bw.RunWorkerAsync();

        }

    }
}
于 2013-09-13T06:56:20.903 に答える