这个LINQ动态orderby方法线程是否安全?

时间:2010-02-26 09:35:03

标签: c# linq

在线搜索并浏览过去的stackoverflow帖子,找到合适的linq动态排序实现后,我想出了我自己的实现,borrows a few things来自我之前见过的其他解决方案。

我需要知道的是这个实现是否是线程安全的?我不相信它是因为我将一个可枚举的泛型类型对象(引用类型)作为参数传递给静态方法但我想知道我是否缺少其他任何东西,并希望如何使它完全线程安全。

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.");
    }
}

1 个答案:

答案 0 :(得分:2)

答案很简单:

如果您的原始集合是线程安全的,那么它是线程安全的。

LINQ中的所有扩展方法只调用原始集合的.GetEnumerator()。排序和排序不会操纵原始集合,而是允许您按排序顺序枚举它。因此,您只对数据执行读操作。作为一般经验法则,如果您只读取数据,则不需要实现任何线程安全性。

我很想说99%的情况下你不需要任何线程安全,因为你只收集一次数据然后公开LINQ功能。如果要创建一个在刷新数据时不实例化新集合的框架,则可能只需要一个线程安全集合,而是继续重用同一个(可观察的)集合实例,该实例以一种奇特的方式与数据库数据同步。

但我不知道你的具体情况。如果确实确实需要线程安全,那么这取决于您是否可以控制实例化原始集合并添加数据的代码。

如果您只使用LINQ到对象,那么完全可以控制在该位置创建线程安全集合类的实例。

如果您正在使用LINQ-to-SQL或其他任何东西,那么它可能很难,因为从数据库收集数据的原始集合可能在提供程序的深处实例化并且对您隐藏。我没有看过它,但是如果有扩展点你可以覆盖东西而不是使用线程安全集合。