2016-12-08 8 views
4

長時間実行する関数があります。私はTaskでそれらをラップして、それぞれが連続して完了するのを待つのではなく、それらをすべて同時に実行できるようにしたいと思います。Staticコンストラクタで呼び出されたときにTask.Run(...)を使用したメソッドをラップします

メソッドが呼び出され、関連するすべてのフィールド値とメソッドおよびプロパティが静的クラス内に存在します。

私はTask.Runでメソッドをラップするとハングしているので、staticクラスコンストラクターが完了しないという問題があります。必要なMininmal, Complete and Verifiable例の要件...

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

namespace MCVEAsyncHang 
{ 
    class Program 
    { 
     private static readonly string[] _foo; 

     static Program() 
     { 
      _foo = Task.WhenAll(Task.Run(new Func<string>(One))).Result; 
     } 

     private static string One() 
     { 
      return "Foo"; 
     } 

     private static void Print() 
     { 
      Console.WriteLine(
       _foo.Aggregate((total, current) => 
        total + string.Format("{0}{1}", Environment.NewLine, current))); 
     } 

     static void Main(string[] args) 
     { 
      Print(); 
      Console.WriteLine("Done"); 
      Console.ReadLine(); 
     } 
    } 
} 

私はちょうど他のいくつかのメソッドを作成して、それを呼び出すことができます理解(と私は(しぶしぶそう)する必要があります場合)に準拠して、それであれば

可能であれば、静的なクラスのコンストラクタ内にこれを保持したいと思います。

+0

あなたは「結果」が何をしているか知っていますか? –

+0

余分なスペースがなく、 "行頭にブレース"形式を使用すると、従来のやり方でコードを再フォーマットしても問題ありませんか?それはちょうど私かもしれませんが、空白がこれを読むのをもっと難しくしています。 –

+0

@JonSkeet読むのが難しくなることは何でもしてください。 – Will

答えて

8

あなたのタスクは別のスレッドで実行され、_oneを呼び出す必要があります。このメソッドは、Programタイプが初期化されるまで実行できません。

タスクのスレッドはProgramタイプがで、すでにがメインスレッドで初期化されていることを確認し、そのスレッドがタイプの初期化を完了するまでブロックします。残念ながら、これは起こりません - あなたのタスクが終了するまで型初期化子がブロックされるためです。デッドロック。

基本的に静的なコンストラクタであまりにも多くの作業をしないでください。起動するタスクは、あまりにも多くの作業のように間違いなく感じます。この場合、デッドロックは明らかですが、それ以外の場合ははるかに微妙なことがあります。 (今の前に私は時間デバッグタイプ初期化子ループを費やしてきた、そしてそれは本当に、本当に楽しいではありませんそれは、単一=スレッド・コードだった - 。私はそれがマルチスレッド環境であることだろうか苦痛考えるのは恐怖。)

+0

だから私は本当に選択肢がありません - 私は別の関数でこれらのメソッドを呼び出さなければなりません。私はこれを前に見てきたのでブックマークする必要がありますが、私が理解できる答えを得ることができたのは初めてです。ありがとう。 – Will

関連する問題