Seasons.NET

ちょっとした技術ブログです

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          }