LINQ在foreach停止响应 [英] LINQ stops responding at foreach
问题描述
我是一名本科生软件工程专业的学生,我建立了一个程序,该程序可以在美国地图上生成热图,这是我研究的一部分.它从SQL数据库或边缘列表文件中读取基于邮政编码的器官移植数据,并使用SQL数据库中的另一个表将邮政编码转换为长/纬度坐标.我创建了一个盈余/赤字模式,用于计算每个拉链的相对器官数(捐赠的器官减去接收的器官).此功能与基于SQL的数据完美配合.但是,边缘列表的新代码使程序在随后的foreach
评估中停止响应.请查看下面的代码,并提出任何问题.请注意,这也是我的第一个大型LINQ项目. =)谢谢!
这是基于SQL的数据的代码,可以顺利运行.
I''m an undergrad Software Engineering student and I have built a program that generates heat maps on top of a map of the US as part of my research. It reads zipcode-based organ transplant data from a SQL database or edge list file and uses another table in the SQL database to transform the zips to long/lat coordinates. I''ve created a surplus/deficit mode that calculates the relative number of organs per zip (donated organs minus received organs). This functionality worked perfectly with SQL-based data. However, the new code for edge lists causes the program to stop responding at a following foreach
evaluation. Please see the code below and ask any questions you have. Kindly note that this is my first big LINQ project too. =) Thanks!
This is the code for the SQL-based data that works without a hitch.
private IQueryable<HeatSource> getHeatDataGeneric(IQueryable<ZipCodes> zips, string organ, HeatField field)
{
IQueryable<AllTrans> organSet = biocomplex.AllTrans.Where(t => t.complete && t.organ == organ);
switch (field)
{
/* irrelevant code removed */
case HeatField.Surplus:
var donated = from z in zips
join t in organSet.GroupBy(t => t.donor_zip) on z.zip equals t.Key
select new { zip = z.zip, longitude = z.longitude, latitude = z.latitude, value = t.Count() };
var received = from z in zips
join t in organSet.GroupBy(t => t.recip_zip) on z.zip equals t.Key
select new { zip = z.zip, longitude = z.longitude, latitude = z.latitude, value = t.Count() };
return donated.Join(received, d => d.zip, r => r.zip, (d, r) => new HeatSource() { longitude = d.longitude, latitude = d.latitude, value = d.value - r.value });
/* irrelevant code removed */
}
}
这是边缘列表的非常相似的代码,后来冻结在foreach
处.构建列表之前的位,并在需要时包含以供参考.
This is the very similar code for edge lists that later freezes at the foreach
. The bit before it builds the List and is included for reference, if necessary.
class Edge
{
public string start;
public string end;
public void pad()
{
start = start.PadLeft(5, ''0'');
end = end.PadLeft(5, ''0'');
}
}
List<Edge> datalist;
private IQueryable<HeatSource> getHeatData(IQueryable<ZipCodes> zips)
{
// Population
if (populationToolStripMenuItem.Checked)
/* irrelevant code removed */
// Edge list
else if (edgeListDonorsToolStripMenuItem.Checked || edgeListRecipientsToolStripMenuItem.Checked || edgeListSurplusDeficitToolStripMenuItem.Checked)
{
if (sourceClicked)
{
datalist = new List<Edge>();
dlgOpenEdgeList.ShowDialog();
string file = dlgOpenEdgeList.FileName;
if (file == "")
return null;
this.Text += ": " + file;
StreamReader sr = new StreamReader(file);
while (sr.Peek() >= 0)
{
string[] line = sr.ReadLine().Split('','');
Edge e = new Edge();
e.start = line[0];
e.end = line[1];
e.pad();
datalist.Add(e);
}
sourceClicked = false;
}
/* dataq contains the expected data (checked using a break) */
IQueryable<Edge> dataq = datalist.AsQueryable();
if (edgeListSurplusDeficitToolStripMenuItem.Checked)
{
/* the Results View of donated and received can''t be viewed when debugging at a breakpoint; the evaluation "times out" */
var donated = from z in zips
join t in dataq.GroupBy(t => t.start) on z.zip equals t.Key
select new { zip = z.zip, longitude = z.longitude, latitude = z.latitude, value = t.Count() };
var received = from z in zips
join t in dataq.GroupBy(t => t.end) on z.zip equals t.Key
select new { zip = z.zip, longitude = z.longitude, latitude = z.latitude, value = t.Count() };
return donated.Join(received, d => d.zip, r => r.zip, (d, r) => new HeatSource() { longitude = d.longitude, latitude = d.latitude, value = d.value - r.value });
}
这段代码是我遇到问题的地方.我正在使用StreamWriter进行一些老式的调试.
This code is where I experience the problem. I was using the StreamWriter to do some old-school debugging.
var heatData = getHeatData(zips);
updateStatus("Grouping raw heat data...");
var heatQ = heatData.AsEnumerable().Select<HeatSource, HeatPoint>(h => new HeatPoint(longLatToPoint(h.longitude, h.latitude), h.value));
heatQ = from h in heatQ
group h by h.point into points
select new HeatPoint(points.Key, points.Sum(p => p.value));
updateStatus("Applying heat radius...");
StreamWriter sw = new StreamWriter(@"C:\Users\Evan Stoner\Documents\!debug.txt", false);
sw.AutoFlush = true;
/* irrelevant code removed */
/* heatQ.Count() will also freeze the program */
//int heatQ_Count = heatQ.Count();
sw.WriteLine("skip heatQ_Count");
sw.WriteLine("starting foreach block");
/* the program stops responding here, and nothing inside the foreach executes */
foreach (var h in heatQ)
{
for (int i = -heatRadius; i <= heatRadius; i++)
{
for (int j = -heatRadius; j <= heatRadius; j++)
{
if (h.point.X + i >= 0 && h.point.X + i < heat.GetLength(0) && h.point.Y + j >= 0 && h.point.Y + j < heat.GetLength(1))
{
sw.Write("pt: " + h.point.X + "\t" + h.point.Y + "\tat: " + i + ",\t" + j);
int diffusedHeat = heatRadius == 0 ? h.value : (int)(h.value - (h.value * Math.Sqrt(Math.Pow(i, 2) + Math.Pow(j, 2)) / heatDistance));
sw.Write("\tdiffused");
heat[h.point.X + i, h.point.Y + j] += diffusedHeat
sw.WriteLine(", set");
}
}
}
}
推荐答案
可以尝试与 ^ ] LINQ查询.这是一个CodeProject文章,可帮助您执行此操作.如何将LINQ查询性能提高5倍? /a> [ ^ ]
在linq中对sql的查询查询已编译为高... [ ^ ]
[6月6日编辑]
延迟的查询执行 [ LINQ和延迟执行 [
May be try working with CompiledQuery[^] LINQ query. Here is a CodeProject article which helps you how to do this.How to improve your LINQ query performance by 5 X times ?[^]
Compiled queries in linq to sql for high...[^]
Deferred Query Execution[^]
LINQ and Deferred Execution[^]
Good luck
这篇关于LINQ在foreach停止响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!