awaitの後に指定できる型は"Awaitable"な型に限ります。現状では、Taskクラス, Task<TResult>クラスに限られます。
アクセス識別子 async Task<戻り値の型> メソッド名(引数型1 引数1, 引数型2 引数2, ... 引数型n 引数n)
public async Task<int> MyMethod(int a, int b, string c)
{
// ... メソッドの実装
}
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 AsyncMethod
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
int ret = await AsyncAdd(1, 2, 3, 4);
textBox1.Text = ret.ToString();
}
private async Task<int> AsyncAdd(int a, int b, int c, int d)
{
await Task.Delay(3000); //3秒後に終了するTask
return a + b + c + d;
}
}
}
private async Task<int> AsyncAdd(int a, int b, int c, int d)
{
await Task.Delay(3000); //3秒後に終了するTask
return a + b + c + d;
}
private async void button1_Click(object sender, EventArgs e)
{
int ret = await AsyncAdd(1, 2, 3, 4);
textBox1.Text = ret.ToString();
}
Task.Delay(3000);
で3秒間処理を停止しますが、呼び出し元のbutton1_ClickのメインスレッドはブロックされずUIはフリーズしません。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 SimpleAsync
{
public partial class FormMain : Form
{
public FormMain()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
int result = await ComplexAsyncTask();
textBox1.Text += Convert.ToString(result);
}
private async void button2_Click(object sender, EventArgs e)
{
int result = await ComplexAsyncTask2();
textBox1.Text += Convert.ToString(result);
}
public async Task<int> ComplexAsyncTask()
{
Func<int> asyncJob = () =>
{
//時間のかかる処理
int i = 0;
for (i = 0; i < 1000000000; i++) {
}
return i;
};
int ret1 = await Task.Run(asyncJob);
int ret2 = await Task.Run(asyncJob);
return ret1 + ret2;
}
public async Task<int> ComplexAsyncTask2()
{
Func<int> asyncJob = Proc;
int ret1 = await Task.Run(asyncJob);
int ret2 = await Task.Run(asyncJob);
return ret1 + ret2;
}
public int Proc()
{
//時間のかかる処理
int i = 0;
for (i = 0; i < 1000000000; i++) {
}
return i;
}
}
}
int result = await ComplexAsyncTask();
を実行することで、非同期のメソッド"ComplexAsyncTask()"を呼び出します。メソッド名の手前に await 演算子があるため、"ComplexAsyncTask()"メソッドの実行が完了するまで、以降の処理は実行されませんが、スレッドがブロックされることもありません。await以降の処理が、"ComplexAsyncTask()"メソッドの終了後に実行されるよう予約されます。