ProcessでCygwinを操作したい!!(3)
id:Ozyさんが修正してくださった例のコードでは、スレッドを用いない方法だった。
あのコードを自分なりちょっとリファクタして、整理したものをあの後作り、
動作も問題ない感じだったのですが、やはりコントロールの操作をスレッドで操作が保証されないというのは
個人的に非常に歯がゆかったので、もうちっと調べてみることにした。
実際、別スレッドからコントロールを操作するには、
いったんメインスレッドで実行してあげる必要があるようだ。
Invokeというメソッドを用いてあげれば良いのだけれど、
@ITサンプルでは、1度実行したら、終了してしまっている。
↓詳しくはこちら。
@IT記事
自分がやりたいのは、監視スレッドで常に回っているスレッドだからちょっと違う。
Invokeを使って、delegateをコールしつづけてば、
メインスレッドに制御が戻る為非常に動作が重くなる・・・というか
スレッドを使っている意味がない。
そうか!!データがあるときだけ、Invokeすれば良いのか。
ということは、こうなる。
ってことでサンプルコード。
これなら、常にinvokeは呼ばれないし、別スレッドからのコールでも処理できることになる。
アプリも重くならない。
実際、今回は、id:Ozyさんのコードとこのスレッドタイプ、どちらでもいいと思う。
要は作り側の好みだ。。。
自分は、スレッドが良かったので今回粘って調べてこうしただけである。
あと、アーカイブしたものもここに置いておきます。
1 /// <summary> 2 /// パケット出力用コールバックデリゲート 3 /// </summary> 4 private static setTextCallback callback = null; 5 6 private delegate void setTextCallback(); 7 /// <summary> 8 /// データ出力管理スレッド 9 /// </summary> 10 private static void processOutput() 11 { 12 while (true) 13 { 14 Thread.Sleep(10); 15 16 if (processAbort_ == true) 17 { 18 break; 19 } 20 if (outputTextBox_ == null) 21 { 22 continue; 23 } 24 if (outputData_.Count > 0) 25 { 26 if (outputTextBox_.InvokeRequired) 27 { 28 outputTextBox_.Invoke(new setTextCallback(outputPacket)); 29 } 30 else 31 { 32 outputPacket(); 33 } 34 } 35 } 36 } 37 private static void outputPacket() 38 { 39 lock (outputData_) 40 { 41 foreach (string text in outputData_) 42 { 43 outputTextBox_.AppendText(text + "\n"); 44 } 45 outputData_.Clear(); 46 } 47 }