1

学生の 1 人から、マルチスレッドを説明する例を作成するように依頼されました。私は、ランダムな回数ループし、ループ中にスリープするスレッドを生成するこの疑似例を思いつきました。各スレッドを識別するために Guid を使用するディクショナリを介して、これらのスレッドを追跡しています。

ディクショナリは、これらのスレッドを監視し、場合によってはそれらを「殺す」ために使用されるページで使用できます。

これは合理的に見えますか:

public class LongProcess
    {
        public static Dictionary<Guid, LongProcess> Monitor = new Dictionary<Guid, LongProcess>();

        public Guid Id { get; set; }

        public int Iterations { get; set; }//number of loops

        public int SleepFactor { get; set; }//rest period while looping

        public int CompletedIterations { get; set; }//number of completed loops


        void Process()
        {
            for(var i = 0 ; i < Iterations; i++)
            {
                Thread.Sleep(1000*SleepFactor);
                SleepFactor = new Random(DateTime.Now.Millisecond).Next(1, 5);
                this.CompletedIterations++;
            }
        }

        public void Start()
        {
            Monitor.Add(Id, this);
            var thread = new Thread(new ThreadStart(Process));
            thread.Start();
        }
    }

このクラスの使用方法は次のとおりです。

    var id = Guid.NewGuid();
    var rnd = new Random(DateTime.Now.Millisecond);
    var process = new LongProcess
                      {
                          Iterations = rnd.Next(5, 20),
                          SleepFactor = rnd.Next(1, 5),
                          Id = id
                      };
    process.Start();

任意のアイデアをいただければ幸いです。

4

3 に答える 3

4

すべての呼び出しがprocess.Start同じスレッドで発生する限り、ディクショナリをロックする必要はありません。これは、LongProcessクラス内で開始されたバックグラウンド スレッドでディクショナリがアクセスされないためです。つまり、クラスLongProcessはスレッドセーフではありませんが、現在のコードでは問題ありません。
安全のために、ロックを回避するために、ConcurrentDictionary<TKey, TValue>.NET4 の新しい を使用できます。

于 2012-04-18T12:42:33.893 に答える
2

他の人が辞書の周りのロックについて答えており、私は彼らに同意します.

私が変更することの 1 つは、プロパティのセッターです。それらは現在公開されているため、スレッドの反復中に基になる値を変更できますが、これは優れた API 設計ではありません。

クラスにコンストラクターを追加して、必要なパラメーターを取得し、セッターをプライベートにして、誰もクラスの値を誤って変更して奇妙な結果にならないようにします。

于 2012-04-18T13:20:56.883 に答える
0

ディクショナリをロックする必要があります。ディクショナリは複数のスレッドによってアクセスされるか、設計上スレッドセーフな System.Collections.Concurrent.ConcurrentDictionary を使用できます。

于 2012-04-18T12:43:46.960 に答える