2016-12-08 5 views
4

장기 실행 함수가 있습니다. 나는 Task에 그들을 포장하고 싶습니다. 그래서 나는 각각을 순차적으로 끝내기를 기다리지 않고 동시에 모든 것을 실행할 수 있습니다.Static 생성자에서 호출하면 Task.Run (...) 메서드를 래핑합니다.

메서드가 호출되며 모든 관련 필드 값과 메서드 및 속성이 정적 클래스 내에 있습니다.

Task.Run 내에서 메서드를 래핑 할 때 정적 클래스 생성자가 정지하기 때문에 문제가 발생합니다. 필요한 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