2010-02-26 5 views
2

온라인 검색 및 linq 동적 순서에 대한 적절한 구현에 대한 과거 stackoverflow 게시물을 통해 갈 때, 나는 내 자신의 구현을 그 전에 내가 본 다른 솔루션 borrows a few things에서 나온.이 LINQ 동적 orderby 메서드는 스레드로부터 안전합니까?

내가 알아야 할 것은이 구현이 threadsafe인지 여부입니다. 그것은 정적 메서드에 매개 변수로 열거 형 제네릭 형식의 개체 (참조 형식)을 전달 오전 믿지 않아요하지만 내가 뭔가를 놓치고 잘하면 완전히 threadsafe 만들 수 있는지 알고 싶습니다.

public class OrderByHelper 
{ 

    public static IEnumerable<T> OrderBy<T>(IQueryable<T> items, string sortColumn, string sortDirection, int pageNumber, int pageSize) 
    { 
     Type t = typeof(T).GetProperty(sortColumn).PropertyType; 
     return (IEnumerable<T>)(typeof(OrderByHelper) 
         .GetMethod("OrderByKnownType") 
         .MakeGenericMethod(new[] { typeof(T), t }) 
         .Invoke(null, new object[] { items, sortColumn, sortDirection, pageNumber, pageSize })); 
    } 

    public static IEnumerable<K> OrderByKnownType<K, T>(IQueryable<K> items, string sortColumn, string sortDirection, int pageNumber, int pageSize) 
    { 
     var param = Expression.Parameter(typeof(K), "i"); 
     var mySortExpression = Expression.Lambda<Func<K, T>>(Expression.Property(param, sortColumn), param); 

     if (!string.IsNullOrEmpty(sortDirection)) 
     { 
      if (sortDirection == "ASC") 
       return items.OrderBy(mySortExpression).Skip((pageNumber - 1) * pageSize).Take(pageSize); 
      else 
       return items.OrderByDescending(mySortExpression).Skip((pageNumber - 1) * pageSize).Take(pageSize); 
     } 
     else 
      throw new InvalidOperationException("No sorting direction specified."); 
    } 
} 

답변

2

대답은 간단하다 : 원래 컬렉션 스레드 안전 경우는 스레드 안전

.

LINQ의 모든 확장 방법은 원래 컬렉션의 .GetEnumerator()을 호출하기 만합니다. 정렬 및 순서 지정은 원래 모음을 조작하지 않고 정렬 된 순서로 열거 할 수있게합니다. 따라서 데이터에 대한 읽기 작업 만 수행합니다. 일반적으로 데이터 읽기 만 수행하면 스레드 안전을 구현할 필요가 없습니다.

데이터를 한 번만 수집 한 다음 LINQ 기능을 노출하기 때문에 99 %의 경우 스레드 안전이 필요 없다고 말하고 싶습니다. 데이터를 새로 고칠 때 새 컬렉션을 인스턴스화하지 않고 멋진 방식으로 데이터베이스 데이터와 동기화되는 동일한 (관찰 가능한) 컬렉션 인스턴스를 계속 유지하면서 프레임 워크를 만들려면 스레드 안전 컬렉션 만 필요합니다.

정확한 시나리오는 모르겠다. 실제로에 스레드 안전성이 필요한 경우 원본 컬렉션이 인스턴스화되고 데이터가 추가되는 코드를 제어 할 수 있는지 여부에 따라 달라집니다.

LINQ- 개체 만 사용하는 경우 해당 지점에서 스레드 안전 컬렉션 클래스의 인스턴스를 만드는 것이 전적으로 사용자의 통제하에 있습니다.

LINQ-to-SQL 또는 기타를 사용하는 경우 데이터베이스에서 데이터를 수집하는 원래 컬렉션이 공급자 내부에서 숨겨지고 사용자로부터 숨겨져 있기 때문에 어려울 수 있습니다. 비록 스레드 안전 컬렉션을 대신 사용하도록 항목을 재정의 할 수있는 확장 점이 있다면 나는 그것을 보지 못했습니다.

관련 문제