使用的IObservable和无框架重写的foreach
-
18-09-2019 - |
题
我在实体框架VS2008。我使用ESQL对其中的功能访问数据库中的对象。我路过一吨ID的SELECT语句,所以我大块它分成套800然后,我的结果,从每个块合并到一起。我的目标是获得结果并行每个块,而不是同步等待。我安装了无功框架和敢肯定我需要利用ForkJoin的。然而,我无法弄清楚如何用到这种功能转换。这里是我的现有代码:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var retList = new List<TElement>();
foreach (var idChunk in chunkedIds)
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
retList.AddRange(query);
}
return retList;
}
谢谢!
EDIT >>> 我修改为使用穷人的作为代码如下:
public static IList<TElement> SelectWhereIn<TElement, TValue>(this ObjectContext context, string fieldName, IList<TValue> idList)
{
var chunkedIds = idList.Split(CHUNK_SIZE);
string entitySetName = typeof(TElement).Name + "Set";
var chunkLists = new List<IEnumerable<TElement>>();
Parallel.ForEach(chunkedIds, idChunk =>
{
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
var retList = new List<TElement>();
foreach (var chunkList in chunkLists)
{
retList.AddRange(chunkList);
}
return retList;
}
这伟大的工作是第一次。但我跑了它的第二次,我得到这个错误:
在连接没有关闭。连接的当前状态连接。 说明:在当前Web请求的执行过程中发生未处理的异常。请检查堆栈跟踪有关该错误的详细信息以及它起源于代码。
异常详细信息:System.InvalidOperationException:连接没有关闭。连接的当前状态被连接。
源错误:
49行:的foreach(在resultList VAR的IAsyncResult) 第50行:{ 线51:del.EndInvoke(IAsyncResult的); 线52:iAsyncResult.AsyncWaitHandle.Close(); 53行:}
有意思的是,B / C埃姆雷(库的作者)有一个编辑给他原来的职位谈论他如何添加这些代码行增加安全性。我使用的是正确的?或者是他的V1毕竟更安全吗?
解决方案
VS2010确实具有与PLINQ。使用扩展AsParallel().WithDegreeOfParallelism(nbProcessors)
会做你所需要的。
使用VS2008中,我使用穷人的Parallel.ForEach迭代器埃姆雷Aydinceren 时,我试图解决性能瓶颈过去,试图给它一个镜头。
编辑:在反应给你添加的错误,它可能是一个在黑暗中随机拍摄,但单独的环境中为每个线程?像这样:
Parallel.ForEach(chunkedIds, idChunk =>
{
ObjectContext context = new MyContext(connStr);//depending what's your config
// like, with or w/o conn string
string delimChunk = string.Join(",", idChunk.Select(x => x.ToString()).ToArray());
ObjectQuery<TElement> query = context.CreateQuery<TElement>("SELECT VALUE x FROM " + entitySetName + " AS x");
query = query.Where("it." + fieldName + " IN {" + delimChunk + "}");
chunkLists.Add(query.ToList());
});
您可能需要调整周围的一些东西(如采取connextion串从上下文扩展到新的实例化上下文)。