2009-07-22 5 views
4
public class TestClass 
{ 
    public TestClass(int id, string name) 
    { 
     Name = name; 
     Id = id; 
    } 
    public string Name 
    { get; private set; } 

    public int Id 
    { get; private set; } 

    public string Tag 
    { get; set; } 

    public DateTime Time 
    { get; set; } 
} 

private static void Main(string[] args) 
    { 
     List<TestClass> list = new List<TestClass>(); 

     for (int i = 0; i < 5; i++) 
     { 
      TestClass t = new TestClass(i, Guid.NewGuid().ToString()); 
      t.Tag = i%2 == 0?"Hello":"World"; 
      list.Add(t); 
     } 

     var query = list 
      .GroupBy(l=>l.Tag); 

     Func<IEnumerable<IGrouping<string, TestClass>>, int[]> func = GetIds<string,TestClass>; 

     func.BeginInvoke(query, null, null); 

     Console.Read(); 
    } 

    private static int[] GetIds<T, U>(IEnumerable<IGrouping<T, U>> query) 
    { 
     List<int> ints = new List<int>(); 

     foreach(var y in query) 
      ints.Add(y.Count()); 

     return ints.ToArray(); 
    } 
} 

나는 컬렉션이 반복 될 때까지 LINQ가 실행되지 않는다는 것을 알고 있지만 쿼리가 다른 비동기식 메서드에 전달 되더라도 여전히 true를 유지한다고 가정 할 수 있습니다.이 LINQ 쿼리는 언제 실행됩니까?

+10

이 기억은, 쿼리는 query_을 나타내는 _an 객체에 불과하다. SQL 쿼리 문자열처럼 생각하면됩니다. 쿼리 문자열을 전달하면 쿼리가 실행되지 않습니다. 쿼리를 실행하면 쿼리가 실행됩니다. –

답변

16

예, 쿼리 실행은 여전히 ​​지연됩니다. 이 쿼리는 단지 IEnumerable<T>의 구현에 대한 참조 일 뿐이며 다른 필터링 (예 : 필터링, 그룹화 등)에 대한 또 다른 IEnumerable<T>을 알고 있습니다.

다시 쿼리를 실행할 두 번째 시간 (모든 스레드에서)을 반복하는 경우주의하십시오. 쿼리 참조는 데이터을 얻는 방법을 으로 알고 있습니다. 데이터 자체를 알지 못합니다.

당신이 ints.ToArray();이 다른 스레드에 있다는 문제가되지해야 호출 할 때 실행
+8

@Downvoter : 의견을 남기세요? –

1

...

편집 : 그렇군요, 그것은 ... foreach 문에서 실행됩니다

+0

글쎄, 그것은 "foreach"비트로 반복됩니다 - ToArray가 호출 될 때까지 질의가 완료되고'ints '와는 관련이 없습니다. –

3

로 이해하지만 여전히 비동기로 유지되지만 실행이 스레드 안전하지 않을 수 있습니다. 예를 들어, LINQ to SQL의 DataContext는 스레드 세이프가 아니므로 LINQ to SQL 쿼리는 다른 방식으로 실행해서는 안됩니다.

1

다음 그림은 전체 쿼리 작업을 보여줍니다. LINQ에서 쿼리 실행은 쿼리 자체와 다릅니다 (아래 참조).

enter image description here

출처 : MSDN

관련 문제