http://msdn.microsoft.com/ja-jp/magazine/jj991977.aspx の前半部分まとめ。
戻り値がvoidのメソッドを非同期呼び出ししない
理由
戻り値が無い為、呼び出し側でタスクの終了を検出することができない為。
戻り値が無い為、タスクで発生した例外を呼び出し側で補足することができない為。
例外
- イベントハンドラーはOK。→ 前項の理由のような挙動でも問題ない。
すべて非同期にする
同期処理と非同期処理、具体例を挙げると await と Task.Waite() を同一処理パスに混在させてはいけない。アプリケーション形態(WindowsFormアプリ、WPFアプリ、SilverLightアプリ、ASP.NETアプリ)によってはデッドロックが発生する。
※なんとなくデッドロック発生のイメージが浮かぶ程度の理解しかできていませんが、下記コードのコメントを見てもらえれば私のイメージが伝わるかと思います。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace AsyncExample
{
public partial class Form2 : Form
{
public Form2()
{
InitializeComponent();
}
private static async Task DelayAsync()
{
//1. 非同期タスク実行
await Task.Delay(1000);
//3. 後続処理をUIスレッドで処理したいがロックされているので、ロック解除待ちする。
MessageBox.Show("完了");
}
private void button1_Click(object sender, EventArgs e)
{
var task = DelayAsync();
//2. タスク完了を同期的に待つ。UIスレッドをロックする。
task.Wait();
}
}
}