Quantcast
Channel: いげ太の日記
Viewing all articles
Browse latest Browse all 26

[C#] Func で BeginInvoke

$
0
0

NOTE: この記事は、当初、ココログの「いげ太のブログ」で公開していたものです。

BackgroundWorker を使うのはなんか違うなと思って。いや、違うっていうか、僕の好みじゃないというデタラメな理由だけど。んー、めんどくさいけどデリゲートでマルチスレッド実装してみるかな、とやってみたら簡単だったという。すげぇな C# 3.0。

僕はデリゲート型ってやつを定義するのがすごく嫌いで、めんどくさくて。でも、C# 3.0 からは Func デリゲートがあるので、それを定義しなきゃいけないような場面はほとんどなくなってしまったようだ。そしてもちろん、Func だって当然 BeginInboke メソッドを持っている。非同期デリゲートによるマルチスレッドがさらにシンプルに書けるようになったってことに、いまさらながら気がついた。

で、想定するのは Outlook の送受信みたいなの。時間のかかる処理をバックグラウンドで走らせつつ、でもフォームの操作は無効化する、みたいな。結局、同期処理的に走らせはするものの、フォームが応答しないというか再描画されないような状況になるのはヤダっていうアレ。

以下、文字列を与えるとその長さを返すメソッドを別スレッドで走らせるという、ろくでもなく役に立たないコードでそれを示す。

public partial class Form1 : Form
{
private Func<int> asyncFoo;

public Form1()
{
InitializeComponent();
}

private void Foo(string s)
{
this.Enabled = false;

this.asyncFoo = delegate() {
System.Threading.Thread.Sleep(2000);
return s.Length;
};
this.asyncFoo.BeginInvoke(new AsyncCallback(FooCallback), null);
}

private void FooCallback(IAsyncResult ar)
{
var i = this.asyncFoo.EndInvoke(ar);

this.Invoke((MethodInvoker)delegate() {
MessageBox.Show(i.ToString());
this.Enabled = true;
});
}

private void button1_Click(object sender, EventArgs e)
{
this.Foo("hogehoge");
}
}

なんだかすごく簡素に見えたんだ。僕には。


Viewing all articles
Browse latest Browse all 26

Trending Articles