await/async等の別スレッドからコントロールのプロパティを変更する
await/async等の別スレッドからコントロールのプロパティを変更しようとすると、
コントロールの描画を行っているスレッドと異なる為、エラーとなる。
InvokeRequired で異なるスレッドからの呼び出しかを判定し、
異なる場合は Invoke で再呼び出しをすることで解決する。
public Form1()
{
InitializeComponent();
button1.Text = "Ready";
}
private async void button1_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
SetButtonText("OK");
});
}
protected delegate void DelegateSetButtonText(string _Text);
private void SetButtonText(string _Text)
{
if (this.InvokeRequired == true)
{
DelegateSetButtonText objDelegate = new DelegateSetButtonText(SetButtonText);
this.Invoke(objDelegate, new object[] { _Text });
}
else
{
button1.Text = _Text;
}
}
また下記のように記載することで、メソッドを分けることなく、
明示的にメインスレッドで処理を行うこともできる。
public Form1()
{
InitializeComponent();
button1.Text = "Ready";
}
private async void button1_Click(object sender, EventArgs e)
{
await Task.Run(() =>
{
Invoke((MethodInvoker)(() =>
{
button1.Text = "OK";
}));
});
}
Private Async Function Update_InstructionPartLabel() As Task
Await Task.Run(
Sub()
Me.Invoke(New MethodInvoker(Sub()
button1.Text = "OK"
End Sub))
End Sub
)
End Function
WPFのVMでは上記Invokeが使用できない為、下記のようになる
System.Windows.Application.Current.Dispatcher.Invoke((Action)(() => {
// 同期処理
}));
ディスカッション
コメント一覧
まだ、コメントがありません