2010-02-26 67 views
2

網上搜索,並通過過去的計算器職位的合適的實現與LINQ動態排序會後,我想到了我自己的實現是borrows a few things從其他解決方案我以前見過。這是LINQ動態orderby方法線程安全嗎?

什麼,我需要知道的是,如果這個實現是線程安全的?我不相信它是因爲我傳遞一個枚舉泛型類型對象(引用類型)作爲參數到靜態方法,但我想知道如果我失去了其他任何東西,並希望如何使它完全線程安全。

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()。排序和排序不會操縱原始集合,而是讓您按排序順序對其進行枚舉。因此,您只能對數據執行讀取操作。作爲一般的經驗法則,如果您只是讀取數據,則不需要實現任何線程安全性。

我很想說,在案件99%,你不需要任何線程安全的,因爲你收集的數據只有一次,然後暴露LINQ功能。如果您想要創建一個在刷新數據時不會實例化新集合的框架,而是不斷重用相同(可觀察)的集合實例,並以奇特的方式與數據庫數據同步,那麼您可能只需要一個線程安全集合。

但我不知道你的確切情況。如果的確是確實需要線程安全,那麼它取決於是否可以控制原始集合實例化和添加數據的代碼。

如果您使用的只是LINQ到對象,那麼它完全在你的控制在該點創建一個線程安全的集合類的一個實例。

如果您使用LINQ到SQL或任何東西的話,由於從數據庫中收集數據的原始採集可能是供應商的深處實例化和隱藏你可能很難。我沒有看過它,但如果有擴展點,你可以重寫的東西來使用線程安全的集合。