Help us understand the problem. What is going on with this article?

C#の非同期処理についてわからなかったので、調べてまとめてみた

More than 1 year has passed since last update.

こんにちは!
非同期処理というものが今までよくわかっていなかったので調べてみました。
使用言語はC#です。

Threadクラスを使用した非同期処理

C#4 以前はThreadクラスを使用して非同期処理を行っていました。
Threadクラスを利用した非同期処理は下記の方法でおこないます。

test.cs
class Program
    {
        static void Main(string[] args)
        {
            //スレッドを作成
            var thread = new Thread(HeavyFunc);
            //非同期処理開始
            thread.Start();
            Console.WriteLine("ワン!");

            //ここで非同期処理が終わるまで待機
            thread.Join();
            //非同期処理が終わってから実行
            Console.WriteLine("スリー!");
        }

        //暫定的な重い処理の見本
        static void HeavyFunc(){
            for (int i = 0; i < 100000; i++){
                for (int p = 0; p < 10000; p++){}
            }
            Console.WriteLine("ツー!");
        }
    }

    //実行結果
    //ワン!
    //ツー!
    //スリー

しかし、この方法だと新しいスレッドを作ったときに古いものを廃棄してから新しいスレッドを作らなければいけませんでした。
そこで、C# 4からTaskが導入されました。

Taskクラスを使用した非同期処理

test.cs
class Program
    {
        static void Main(string[] args)
        {
            //非同期処理開始
            Task task = Task.Run(() => HeavyFunc());
            Console.WriteLine("ワン!");

            //ここで非同期処理が終わるまで待機
            task.Wait();
            //非同期処理が終わってから実行
            Console.WriteLine("スリー!");
        }

        //暫定的な重い処理の見本
        static void HeavyFunc(){
            for (int i = 0; i < 100000; i++){
                for (int p = 0; p < 10000; p++){}
            }
            Console.WriteLine("ツー!");
        }
    }

このTaskがThreadと何が違うのかというと、
非同期処理を行うとメインのスレッドの他にサブのスレッドを作成して非同期の処理を行うわけですが、このスレッド作成処理が負荷が高いため、一度使い終わったスレッドを「スレッドプール」において、別の処理のときに再利用します。
たくさんのスレッドを使用するアプリケーションで重要になります。

async await

test.cs
class Program
    {
        static void Main(string[] args)
        {
            //非同期処理開始
            Task<string> task = StartAsync();
            Console.WriteLine("ワン");

            //ここで非同期処理が終わるまで待機
            task.Wait();
            //StartAsyncから帰ってきた返り値を使える
            Console.WriteLine(task.Result);
        }

        //メソッドを定義
        static async Task<string> StartAsync(){
            await Task.Run(() => HeavyFunc());
            Console.WriteLine("スリー");
            return "フォー";
        }

        //暫定的な重い処理の見本
        static void HeavyFunc(){
            for (int i = 0; i < 100000; i++){
                for (int p = 0; p < 10000; p++){}
            }
            Console.WriteLine("ツー!");
        }
    }

async awaitでは非同期処理から返り値をとることができます。

以上が非同期処理の説明でした!

Why do not you register as a user and use Qiita more conveniently?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away