3

私が持っている静的クラスにスレッドを追加しようとしていて、多くの問題に遭遇しました。このスレッドとリンク先のブログ投稿を読んで、何が起こっているのか理解できたと思います。しかし、次の例のように Parallel For ループがまだ機能する理由がわかりません。

using System;
using System.Threading;
using System.Threading.Tasks; 

namespace ThreadingTest
{
    public static class TestClass
    {
        public static int AwesomeNum = 43; 

        static TestClass()
        {
            string[] x = { "deal", "witch", "panda"};

            //does not cause a deadlock? huh?
            Parallel.For(0, x.Length,  i =>
                {
                    Console.WriteLine(x[i]); 
                });

            //results in a deadlock
            //Parallel.Invoke(writesomething, writesomethingelse); 

            //results in deadlock
            Thread thread = new Thread(new ThreadStart(() =>
            {
                Console.WriteLine("there is a bear in my soup"); 
            }));

            thread.Start();
            thread.Join(); 
        }

        private static void writesomething()
        {
            Console.WriteLine("writing something"); 
        }

        private static void writesomethingelse()
        {
            Console.WriteLine("writing something else."); 
        }
    }
}


using System;

namespace ThreadingTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(TestClass.AwesomeNum.ToString()); 
        }
    }
}
4

1 に答える 1

7

次の場合、デッドロックが発生します。

Parallel.For(0, x.Length,  i => {
   Console.WriteLine(i); 
});

違いは何ですか?

上で書いたラムダ式は、 内のメソッドとしてコンパイルされTestClassます。あなたのnew Thread例で書いたものもそうです。

並列式で記述したラムダ は、i => Console.WriteLine(x[i])をキャプチャするため、コンパイラによって生成された別のクラスにコンパイルされxます。したがって、実行するには、クロージャ クラスを静的に初期化する必要がありますが、TestClass.

Parallelしたがって、他のスレッドメカニズムとは関係ありません。これは、クロージャ オブジェクトの生成を必要とするラムダと必要としないラムダの違いにすぎません。

注、現在のコンパイラの動作について説明しています。この動作は、関連する仕様に記載されているか、実装によって定義されている可能性があります。私は見ていません。

于 2013-04-02T21:35:34.120 に答える