1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Invoke,BeginInvokeの基本的な動作

Posted at

Invoke,BeginInvokeの基本的な動作

Invoke,BeginInvoke共通

要求された処理はUIスレッドで実行される

BeginInvoke

  1. BeginInvokeは呼び出し元に対して非同期的に実行される
    (呼び出し元がブロックされない)
  2. BeginInvokeにより要求された処理はキューに登録され、後から先着順で1件ずつ実行される
  3. BeginInvokeによりキューに登録された処理が実行されるのは、UIスレッドが空いたタイミング、または、どこかの処理でInvokeが呼び出されたタイミング

Invoke

  1. 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
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?