Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这个LINQ动态orderby方法是线程安全的吗?_C#_Linq - Fatal编程技术网

C# 这个LINQ动态orderby方法是线程安全的吗?

C# 这个LINQ动态orderby方法是线程安全的吗?,c#,linq,C#,Linq,在网上搜索并浏览了过去的stackoverflow帖子,寻找一个适合使用linq进行动态排序的实现之后,我找到了我自己的实现,这是我以前见过的其他解决方案的实现 我需要知道的是,这个实现是否是线程安全的?我不相信这是因为我正在将一个可枚举泛型类型对象(引用类型)作为参数传递到静态方法中,但我想知道我是否遗漏了其他内容,并希望知道如何使其完全线程安全 public class OrderByHelper { public static IEnumerable<T> Order

在网上搜索并浏览了过去的stackoverflow帖子,寻找一个适合使用linq进行动态排序的实现之后,我找到了我自己的实现,这是我以前见过的其他解决方案的实现

我需要知道的是,这个实现是否是线程安全的?我不相信这是因为我正在将一个可枚举泛型类型对象(引用类型)作为参数传递到静态方法中,但我想知道我是否遗漏了其他内容,并希望知道如何使其完全线程安全

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.");
    }
}
公共类OrderByHelper
{
公共静态IEnumerable OrderBy(IQueryable项、字符串sortColumn、字符串sortDirection、int pageNumber、int pageSize)
{
Type t=typeof(t).GetProperty(sortColumn).PropertyType;
返回(IEnumerable)(类型(OrderByHelper)
.GetMethod(“OrderByKnownType”)
.MakeGenericMethod(新[]{typeof(T),T})
.Invoke(null,新对象[]{items,sortColumn,sortDirection,pageNumber,pageSize});
}
公共静态IEnumerable OrderByKnownType(IQueryable项、字符串sortColumn、字符串sortDirection、int pageNumber、int pageSize)
{
var param=表达式参数(typeof(K),“i”);
var mySortExpression=Expression.Lambda(Expression.Property(param,sortColumn),param);
如果(!string.IsNullOrEmpty(sortDirection))
{
如果(排序方向==“ASC”)
返回items.OrderBy(mySortExpression)。跳过((pageNumber-1)*pageSize)。获取(pageSize);
其他的
返回项。OrderByDescending(mySortExpression)。跳过((pageNumber-1)*pageSize)。获取(pageSize);
}
其他的
抛出新的InvalidOperationException(“未指定排序方向”);
}
}
答案很简单:

如果您的原始收藏是线程安全的,那么它是线程安全的

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

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

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

如果您仅使用LINQ to对象,那么在该位置创建线程安全集合类的实例完全由您控制

如果您使用的是LINQtoSQL或其他任何东西,那么可能会很困难,因为从数据库收集数据的原始集合可能在提供程序的深处实例化,并且对您隐藏。不过,我还没有研究过是否存在扩展点,您可以在这些扩展点上重写内容,以使用线程安全的集合