「C Sharpの基礎 - マルチスレッドとGUI」の版間の差分

ナビゲーションに移動 検索に移動
(Wiki がページ「マルチスレッドにおけるGUIコントロールの操作(C Sharp)」を「C Sharpの基礎 - マルチスレッドとGUI」に、リダイレクトを残さずに移動しました)
169行目: 169行目:
  {
  {
     source.Cancel();
     source.Cancel();
}
</syntaxhighlight>
<br><br>
== マルチスレッドとプログレスバー ==
マルチスレッドの実行は、<code>async</code>および<code>await</code>を使用して簡潔に記述できる。<br>
ただし、マルチスレッド処理ではコントロール(ユーザインターフェイス)を直接操作できない。(例外が発生する)<br>
<br>
マルチスレッド内でプログレスバー(<code>Progress</code>クラス)を制御する場合、まず、<code>Progress</code>オブジェクトに進捗を表示するためのメソッドを登録する。<br>
マルチスレッドのメソッドの引数には、<code>IProgress</code>インターフェース(<code>System</code>名前空間)を追加する。<br>
<br>
マルチスレッド処理内で<code>Progress</code>オブジェクトの<code>Report</code>メソッドを呼ぶと、<code>Progress</code>オブジェクトに登録されているメソッドがUIスレッドで実行される。<br>
<br>
また、マルチスレッド処理内でのキャンセル処理も進捗表示と似た方法で行う。<br>
なお、キャンセル処理は<code>CancellationToken</code>構造体(<code>System.Threading</code>名前空間)を使用するが、上記の進捗表示より複雑になることに注意する。<br>
<syntaxhighlight lang="c#">
private async void button2_Click(object sender, EventArgs e)
{
    DisableAllButtons();
    toolStripStatusLabel1.Text = "処理中…";
    toolStripProgressBar1.Value = 0;
    // Progressクラスのインスタンスを生成
    var p = new Progress<int>(ShowProgress);
    // 時間のかかる処理を別スレッドで開始
    string result = await Task.Run(() => DoWork(p, 100));
    // 処理結果の表示
    toolStripStatusLabel1.Text = result;
    toolStripProgressBar1.Value = 100;
    MessageBox.Show("正常に完了");
    EableAllButtons();
}
// 進捗を表示するメソッド(UIスレッドで呼び出される)
private void ShowProgress(int percent)
{
    toolStripStatusLabel1.Text = percent + "% 完了";
    toolStripProgressBar1.Value = percent;
}
// 時間のかかる処理を行うメソッド(進捗付き)
private string DoWork(IProgress<int> progress, int n)
{
    // 別スレッドで実行されるため、このメソッドではUI(コントロール)を操作してはいけない
    // 時間のかかる処理
    for (int i = 1; i <= n; i++)
    {
      System.Threading.Thread.Sleep(100);
      int percentage = i * 100 / n; // 進捗率
      progress.Report(percentage);
    }
    return "全て完了";
}
private void DisableAllButtons()
{
    button1.Enabled = false;
    button2.Enabled = false;
}
private void EableAllButtons()
{
    button1.Enabled = true;
    button2.Enabled = true;
  }
  }
  </syntaxhighlight>
  </syntaxhighlight>

案内メニュー