3
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?

More than 3 years have passed since last update.

C# > Task.AsyncStateの動作を確認する

Last updated at Posted at 2016-01-06

背景

前回、C# > Taskに引数を渡し復帰値を取得するでTaskについて学び、Task.AsyncStateの存在を知りました。
そこで今回はそのAsyncStateプロパティの動作について確認することにしました。

ちょっと気になった点 その1

Taskをnewする時にTaskとかRunとかStartNewで書いたら、IDEから「もっとシンプルに書けるよ。<int>はいらないよ。」と言われました。確かに削除してもコンパイルは通りましたが、意味論的に同等なのかよく分かっておりません。

ちょっと気になった点 その2

AsyncStateプロパティの型はobjectです。なので、中身を参照する時は元々の設定時の型にキャストしてやる必要があります。ジェネリックがある時代なのにキャストしなければならないという点がどうも腑に落ちません。stateの型はobjectだからAsyncStateプロパティの型もobjectなんですよね。Tにできない理由があるのでしょうか。T stateみたいな。

サンプル

GitHub TestTask

Program.cs
using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace TestTask
{
    class Program
    {
        static void Main(string[] args)
        {
            const int MaxCount = 10;
            int previous = -1;
            int current = 0;
            State state = new State() { Count = MaxCount, Current = 0 };

            // 呼び出し方法 その1
            // Taskのインスタンスを作ってからStartする。
            //
            //var task = new Task<int>(o => CountUpMethod((State)o), state);
            //task.Start();

            // 呼び出し方法 その2
            // Taskのインスタンスを作ってからRunするが、
            // stateはTaskのインスタンスに渡していない為、
            // task.AsyncStateがnullになり、NullReferenceExceptionが発生する。
            //
            //var task = Task.Run(() => CountUpMethod(state));

            // 呼び出し方法 その3
            // TaskのFactoryのStartNewでインスタンスの作成とスタートを同時に実行する。
            // また、stateをTaskのインスタンスに渡している(インスタンス内にstateが保存される) 
            var task = Task.Factory.StartNew(o => CountUpMethod((State)o), state);

            while (current < MaxCount)
            {
                current = ((State)task.AsyncState).Current;
                if(current != previous )
                {
                    Console.Write($"{current} ");
                    previous = current;
                }
# if DEBUG
                Debug.WriteLine($"{current}");
# endif
            }

            Console.WriteLine("\n\nPush any key!");
            Console.ReadKey();
        }

        static int CountUpMethod(State state)
        {
            int count = 0;

            for (int i = 0; i < state.Count; i++)
            {
                count++;
                state.Current = count;
                Thread.Sleep(1000); // 1秒
            }

            return count;
        }
        
    }

    class State
    {
        public int Current { get; set; }
        public int Count { get; set; }
    }
}

実行結果

コンソール
0 1 2 3 4 5 6 7 8 9 10

Push any key!

[出力]ウィンドウ
1
1
1
(省略)
2
2
2
(省略)
9
9
9
(省略)
10

3
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
3
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?