13,005
回編集
37行目: | 37行目: | ||
== Invokeメソッドを使う == | == Invokeメソッドを使う == | ||
コントロールの<code>Invoke</code>メソッドを使用する場合、呼び出し元のオブジェクトのスレッドにおいてデリゲートを実行することができる。<br> | |||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
private async void buttonl_Click(object sender, RoutedEventArgs e) | private async void buttonl_Click(object sender, RoutedEventArgs e) | ||
54行目: | 52行目: | ||
})); | })); | ||
}); | }); | ||
} | |||
</syntaxhighlight> | |||
<br> | |||
また、コントロールの<code>Invoke</code>メソッドと<code>InvokeRequired</code>プロパティを組み合わせて使用することもできる。<br> | |||
* <code>Invoke</code>メソッド | |||
*: 指定された処理をそのコントロールが生成されたスレッドで実行する。 | |||
*: 多少オーバーヘッドが発生する。 | |||
* <code>InvokeRequired</code>プロパティ | |||
*: コントロールにアクセスする時、<code>Invoke</code>メソッドを使用する必要があるかどうかを判断する。 | |||
<syntaxhighlight lang="c#"> | |||
// 必要に応じてInvokeするコード | |||
public partial class Form1 : Form | |||
{ | |||
// ...略 | |||
private async void buttonl_Click(object sender, RoutedEventArgs e) | |||
{ | |||
InvokeIfRequired(button1, () => button1.Enabled = false); | |||
InvokeIfRequired(button1, () => button1.Enabled = true); | |||
} | |||
private void InvokeIfRequired(Control control, Action action) | |||
{ | |||
if (control.InvokeRequired) | |||
{ | |||
control.Invoke(action, new object[] { }); | |||
} | |||
else | |||
{ | |||
action(); | |||
} | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
また、以下のようなコントロールに対する拡張メソッドとして定義することにより、簡潔に記述できるようになる。<br> | |||
<syntaxhighlight lang="c#"> | |||
public partial class Form1 : Form | |||
{ | |||
// ...略 | |||
private async void buttonl_Click(object sender, RoutedEventArgs e) | |||
{ | |||
button1.InvokeIfRequired(() => button1.Enabled = false); | |||
button1.InvokeIfRequired(() => button1.Enabled = true); | |||
} | |||
// ...略 | |||
} | |||
// コントロールに対する拡張メソッド | |||
public static class ControlExtensions | |||
{ | |||
// 戻り値が不要な場合 | |||
public static void InvokeIfRequired(this Control control, Action action) | |||
{ | |||
if (control.InvokeRequired) | |||
{ | |||
control.Invoke(action, new object[] { }); | |||
} | |||
else | |||
{ | |||
action(); | |||
} | |||
} | |||
// 戻り値が必要な場合 | |||
public static T InvokeIfRequired<T>(this Control control, Func<T> func) | |||
{ | |||
if (control.InvokeRequired) | |||
{ | |||
return (T)control.Invoke(func, new object[] { }); | |||
} | |||
else | |||
{ | |||
return func(); | |||
} | |||
} | |||
} | } | ||
</syntaxhighlight> | </syntaxhighlight> |