何もない空虚

動画を作っていたりいなかったり

同期・非同期の話(主にC#) 

こんにちは、午前11時、金曜ですね。

ここ最近ドライヤーの調子が悪くて、風の勢いが凄く弱くなってて困ってました。
なので価格コムでぼちぼち評判が良くてぼちぼち安いTID956ってやつを買いました。

レビューでやたら「音がうるさい」って書いてあったんですが、ドライヤーに静音性ってそんなに必要なんですかね。
実際に使ってみても全然大した音じゃなかったです、レビュワーって神経質な人多そうですしね…。

一応個人的な評価をば。
・デザイン:-(ドライヤーにデザイン性は求めてないので)
・使いやすさ:5(普通のドライヤーです)
・スタイリング:5(風が強くて良い、温風冷風両方対応してるのがありがたい)
・乾燥スピード:5(風が強くて温風が出れば乾燥するのが早いのは当たり前かなと)
・静音性:4(神経質な人にとってはうるさいかもです、ただターボモードの音はかなりでかかったです、使わないけど)

で、本題。

あいも変わらず現場ではC#をゴリゴリ書いてるんですが。
同期・非同期のことをネットで調べるとあまりわかりやすくまとめてくれているサイトがないので、備忘録がてら書いておこうかなと。

・そもそも同期・非同期ってなに?

フォームアプリケーション上において、重い処理を実行するとフォームがフリーズすることが多々あると思います。
で、なんでフォームがフリーズするかというと、フォーム上(以下UIスレッド)で重たい処理を走らせているからなわけです。(当たり前ですが)

じゃあどうしたらフォームをフリーズしないように出来るかというと、UIスレッド以外のスレッドにおいて重たい処理を走らせれば良いということなります。

端的に書くと、UIスレッドのみで処理を実行することを同期実行、UIスレッドより別スレッドを呼び出して複数のスレッドにおいて処理を実行することを非同期実行と呼ぶみたいです、多分。(参考

・C#において非同期な処理ってどうやって書くのさ

ここが一つ大きなポイントで、『別スレッドを呼び出すんだからUIスレッドからThreadクラスを呼び出せばええんやな!』と考えちゃう人が多いみたいです。
が、Threadクラスてやつは過去の産物、非同期処理では使って何一つメリットがありません。(書き方ややこしいし)

じゃあ何を使うんだというと、.Net Framework4より追加されたTaskクラスを使います。
(備考的に書くと、.Net Framework3.5においてもライブラリを追加するとTaskクラスが使用できます。)

・話がややこしくてわからん!具体的な例を出せ!

例)button1を押下した場合、10秒後にtextBox1に"Finished"という文字列を表示する。

まず同期的に書くとこんな感じです。

private void button1_Click(object sender, EventArgs e)
{
Thread.Sleep(10000);

textBox1.Text = "Finished";
}

このコードでbutton1を押下すると、10秒間フォームがフリーズした後に、textBox1に"Finished"という文字列が表示されます。

で、フォームがフリーズするのは嫌なので、非同期的に書き直すとこんな感じになります。

private async void button1_Click(object sender, EventArgs e)
{
await Task.Delay(10000);

textBox1.Text = "Finished";
}

これだとbutton1を押下後の10秒間フォームがフリーズすることなく、10秒後にtextBox1に"Finished"という文字列が表示されます。
多分UIスレッドから別スレッドを呼び出して、別スレッド上で重たい処理(10秒待機)を実行させて、その処理が完了するのをawaitで待っているんだと思います、多分。

ただ実際には、「ボタンを押してから10秒待って文字列を表示する」というアホみたいな処理を使うことはないと思うので、もう少し複雑な処理にも対応できるように、処理をわかりやすく書きなおしてみます。

private async void button1_Click(object sender, EventArgs e)
{
string result = await WaitAsynchronouslyAsync();

textBox1.Text = result;
}

public async Task WaitAsynchronouslyAsync()
{
await Task.Delay(10000);

return "Finished";
}

一先ずこんなところで。
まとめとしては、以下の様な感じです。

・フォームがフリーズする時はTaskクラスを使いましょう。
・Threadクラスは使わない。

もう少し突っ込んだ内容については、また気が向いたら書きます。
trackback: -- | コメント: -- | edit