Invoke,BeginInvokeの基本的な動作
Invoke,BeginInvoke共通
要求された処理はUIスレッドで実行される
BeginInvoke
- BeginInvokeは呼び出し元に対して非同期的に実行される
(呼び出し元がブロックされない) - BeginInvokeにより要求された処理はキューに登録され、後から先着順で1件ずつ実行される
- BeginInvokeによりキューに登録された処理が実行されるのは、UIスレッドが空いたタイミング、または、どこかの処理でInvokeが呼び出されたタイミング
Invoke
- Invokeは呼び出し元に対して同期的に実行される
(処理が完了するまで呼び出し元はブロックされる)
Invokeでは処理が完了するまで呼び出し元をブロックする。Invoke実行時にBeginInvokeの積み残しがすべて処理されるので、Invokeで呼び出す処理自体は軽いものでも、呼び出し元が長時間ブロックされる可能性がある)
例
Example.cs
using System.Diagnostics;
namespace WinFormsApp1
{
public partial class Form1 : Form
{
static DateTime StartTime = DateTime.Now;
static void ResetStartTime()
{
StartTime = DateTime.Now;
}
static void PrintThreadID(string text = "")
{
int id = System.Threading.Thread.CurrentThread.ManagedThreadId;
Debug.WriteLine($"{(StartTime - DateTime.Now).ToString(@"ss\.fff")}:[{id}]{text}");
}
public Form1()
{
InitializeComponent();
}
private async void button1_Click(object sender, EventArgs e)
{
ResetStartTime();
PrintThreadID($"start");
//BeginInvokeの実行順・完了順は変わらない
for (int i = 0; i < 10; i++)
{
var temp = i;
var ret = BeginInvoke(() =>
{
PrintThreadID($"BeginInvoke-{temp}-start");
Thread.Sleep(100*(10-temp));
PrintThreadID($"BeginInvoke-{temp}-end");
});
}
//middleまではBeginInvokeに先だって完了する
PrintThreadID($"middle");
//BeginInvokeが全て完了するまでInvokeの処理は始まらない
//Invokeの実行順・完了順は変わらない
for (int i = 0; i < 10; i++)
{
var temp = i;
Invoke(() =>
{
PrintThreadID($"Invoke-{temp}-start");
Thread.Sleep(100 * (10 - temp));
PrintThreadID($"Invoke-{temp}-end");
});
}
PrintThreadID($"end");
}
}
}
00.005:[1]start
00.029:[1]middle
00.032:[1]BeginInvoke-0-start
01.047:[1]BeginInvoke-0-end
01.137:[1]BeginInvoke-1-start
02.137:[1]BeginInvoke-1-end
02.143:[1]BeginInvoke-2-start
02.954:[1]BeginInvoke-2-end
02.957:[1]BeginInvoke-3-start
03.664:[1]BeginInvoke-3-end
03.669:[1]BeginInvoke-4-start
04.286:[1]BeginInvoke-4-end
04.289:[1]BeginInvoke-5-start
04.795:[1]BeginInvoke-5-end
04.802:[1]BeginInvoke-6-start
05.219:[1]BeginInvoke-6-end
05.222:[1]BeginInvoke-7-start
05.532:[1]BeginInvoke-7-end
05.535:[1]BeginInvoke-8-start
05.752:[1]BeginInvoke-8-end
05.757:[1]BeginInvoke-9-start
05.864:[1]BeginInvoke-9-end
05.868:[1]Invoke-0-start
06.885:[1]Invoke-0-end
06.887:[1]Invoke-1-start
07.794:[1]Invoke-1-end
07.800:[1]Invoke-2-start
08.611:[1]Invoke-2-end
08.618:[1]Invoke-3-start
09.333:[1]Invoke-3-end
09.335:[1]Invoke-4-start
09.942:[1]Invoke-4-end
09.945:[1]Invoke-5-start
10.460:[1]Invoke-5-end
10.463:[1]Invoke-6-start
10.870:[1]Invoke-6-end
10.873:[1]Invoke-7-start
11.187:[1]Invoke-7-end
11.190:[1]Invoke-8-start
11.407:[1]Invoke-8-end
11.410:[1]Invoke-9-start
11.517:[1]Invoke-9-end
11.520:[1]end