LoginSignup
39
37

More than 5 years have passed since last update.

C# で Thread.Sleep はあきまへん

Posted at

ちいさな Tips。サンプルでよく使いますが、しばらく止まって欲しいときってありますよね。そのケースに、Thread.Sleep とかよく使うようです。ただ、これは、あまり使わないほうが良さげですね。

例えば次のようなサンプルを書いてみました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AwaitSample
{

    class Program
    {
        async Task<string> getMessageAsync(string message)
        {
            Console.WriteLine("getMessage!");
            System.Threading.Thread.Sleep(3000);
            Console.WriteLine("finished!");
            return "message:" + message;
        }
        async void executeAsync()
        {
            Console.WriteLine("step 1");
            var result = await getMessageAsync("hello");
            Console.WriteLine(result);
            Console.WriteLine("step 2");
        }
        static void Main(string[] args)
        {
            var program = new Program();
            program.executeAsync();
            Console.WriteLine("step 3");
            Console.ReadLine();
        }
    }
}

結果は step 1, 2, 3 が順に実行されてしまいます。私の想定では、step 1, getMessage! の後は、executeAsync() は非同期なので、先に step 3 が表示されると思っていました。

step 1
getMessage!
finished!
message:hello
step 2
step 3

理由は簡単で、Thread.Sleep Method は、スレッドを止めるメソッドだから、スレッドがブロックされます。だから、この非同期処理が、メインと同じスレッドを使っているとしたら、メイン側のスレッドも停止します。

この場合は、TaskDelay() メソッドを使ってみます。Task.Delay Method (TimeSpan, CancellationToken) こちらは特定の時間の後、Taskの実行が終了しますので、スレッドをブロックしません。

            // System.Threading.Thread.Sleep(3000);
            await Task.Delay(3000);
step 1
getMessage!
step 3
finished!
message:hello
step 2

めでたしめでたし。

39
37
1

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
39
37