だらだらやるよ。

こげつのIT技術メモ

C#で非同期処理してみる。

何回か書いてたのだけど、すぐ忘れるのでメモ代わりにまとめ

なんか色々方法はあるみたいだけど、とりあえず非同期デリゲートが簡単みたい。
というわけで書いてみた。
まずは非同期実行したい処理をメソッドに分割。

private void Test(){
	for(int i = 0;i < 10;i++) {
		Console.WriteLine(i+"回目:子です。");
		Thread.Sleep(1000);
	}
}

そのメソッドに対応するデリゲートを定義します。

private delegate void TestDelegate();

あとはこんな感じで実行すればオッケー

private void Exec(){
	TestDelegate t = new TestDelegate(Test);
	t.BeginInvoke(null,null);
	Console.WriteLine("親です。");
}

コンソールには子のメッセージより先に親のメッセージが表示されるはずです。

ここまではネットのサンプルをだらだら見ながら書けたのですが、
フォームに1個ラベルを置いて、以下のように書き直してみるとうまくいきませんでした、

private void Test(){
	for(int i = 0;i < 10;i++) {
		label1.Text = i+"回目:子です。";//例外
		Thread.Sleep(1000);
	}
}

親プロセスで作成されたコントロールの値は子から触れないみたいです。
ちょろちょろと調べたらこんな感じで書いたらオッケーみたい。

private void Test() {
	for(int i = 0;i < 10;i++) {
		if(this.InvokeRequired) {
			SetLabelDelegate sl = new SetLabelDelegate(SetLabel);
			this.Invoke(sl,i);
		}
		Thread.Sleep(1000);
	}
}
private delegate void SetLabelDelegate(int i);
private void SetLabel(int i) {
	label1.Text = i + "回目:子です。";
}

ちょっと面倒だけど、仕方ないかな?
時間のかかる処理からコントロールにあまり触らせないようにしたいですね:-)