対処方法は2つありあます。コードは以下のとおり。
■Invokeを使う(正統派)
/// <summary>
/// Invokeを使ったマルチスレッド処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnInvoke_Click(object sender, EventArgs e)
{
//Threadを生成する
Thread thread = new Thread(delegate() {
//50回ループする
for (int i = 0; i < 50; i++)
{
Thread.Sleep(500);
//描画処理をinvokeする
textBox.Invoke(new MethodInvoker(delegate() {
textBox.Text = i.ToString();
textBox.Update();
}));
}
});
thread.Start();
}
/// Invokeを使ったマルチスレッド処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnInvoke_Click(object sender, EventArgs e)
{
//Threadを生成する
Thread thread = new Thread(delegate() {
//50回ループする
for (int i = 0; i < 50; i++)
{
Thread.Sleep(500);
//描画処理をinvokeする
textBox.Invoke(new MethodInvoker(delegate() {
textBox.Text = i.ToString();
textBox.Update();
}));
}
});
thread.Start();
}
しかし、旧来のシステムを移行する場合これらの対応を入れていくのは非常にメンドクサイ。別途動作確認をし、問題点のみInvokeを使って解決することを前提とすれば、フラグの制御のみでマルチスレッド化が実現できる。
■Control.CheckForIllegalCrossThreadCallsを使う(下位互換)
/// <summary>
/// CheckForIllegalCrossThreadCallsを使ったマルチスレッド処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNoInvoke_Click(object sender, EventArgs e)
{
//Control.CheckForIllegalCrossThreadCallsをtrueにすればInvokeとほぼ同等になる
//Control.CheckForIllegalCrossThreadCalls = true;
//Threadを生成する
Thread thread = new Thread(delegate()
{
//50回ループする
for (int i = 0; i < 50; i++)
{
//500ms待機してテキストを更新する
Thread.Sleep(500);
textBox.Text = i.ToString();
textBox.Update();
}
});
thread.Start();
}
/// CheckForIllegalCrossThreadCallsを使ったマルチスレッド処理
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnNoInvoke_Click(object sender, EventArgs e)
{
//Control.CheckForIllegalCrossThreadCallsをtrueにすればInvokeとほぼ同等になる
//Control.CheckForIllegalCrossThreadCalls = true;
//Threadを生成する
Thread thread = new Thread(delegate()
{
//50回ループする
for (int i = 0; i < 50; i++)
{
//500ms待機してテキストを更新する
Thread.Sleep(500);
textBox.Text = i.ToString();
textBox.Update();
}
});
thread.Start();
}
私自身は実験していませんが、デバッグモードでは実行時にエラーとなるが、リリースモードでは実行時にエラーにならないらしいです。移行の過渡期なんだろうか。。。
0 件のコメント:
コメントを投稿