ArcGIS 在 C# 中分配内存时崩溃

发布于 2024-08-01 17:12:05 字数 1451 浏览 1 评论 0原文

我正在开发一个 ArcGIS 自定义工具,它将与 ArcView 集成。 该工具使用 C# 开发,基本上连接到 SQL 数据库,将数据获取到本地数据结构,执行大量统计分析,然后将结果显示为新层。

崩溃发生在这段代码的执行过程中。

LinkedList<SegmentDbRecord> segmentData = new LinkedList<SegmentDbRecord>();
while( dataReader.Read() )
{
  SegmentDbRecord record = new SegmentDbRecord();

  record.first_stop_id = dataReader.GetInt32(0);
  record.first_stopway = dataReader.GetString(1);
  record.first_stopway_X = dataReader.GetString(2);

  record.second_stop_id = dataReader.GetInt32(3);
  record.second_stopway = dataReader.GetString(4);
  record.second_stopway_X = dataReader.GetString(5);

  record.segment_start = Tools.timeToFloat((DateTime)dataReader.GetValue(6));
  record.segment_finish = Tools.timeToFloat((DateTime)dataReader.GetValue(7));

  record.stop1_long = dataReader.GetFloat(8);
  record.stop1_lat = dataReader.GetFloat(9);
  record.stop2_long = dataReader.GetFloat(10);
  record.stop2_lat = dataReader.GetFloat(11);

  record.max_speed = dataReader.GetInt32(12);
  record.avg_speed = dataReader.GetInt32(13);
  record.route_hnd = dataReader.GetInt32(14);
  record.seq_1 = dataReader.GetInt32(15);
  record.seq_2 = dataReader.GetInt32(16);
  record.route_name = dataReader.GetString(17);

  segmentData.AddFirst(record);

}

在此阶段,我只是将查询结果保存在链接列表中。 我很确定崩溃是在内存分配期间发生的,但我知道仍然有足够的内存,并且查询没有返回如此大的数据集。 运行分配新“记录”的简单循环也会很快崩溃。 你们中有人知道 ArcGIS 运行时中的内置保护可以阻止我分配超过一定数量的内存吗?

谢谢 !

I am working on a custom tool for ArcGIS which will integrate with ArcView. The tool is developped using C# and basically connects to an SQL database, fetches data to a local data structure, performs a great deal of statistical analysis and then displays the results as a new layer.

The crash happens during this code's execution.

LinkedList<SegmentDbRecord> segmentData = new LinkedList<SegmentDbRecord>();
while( dataReader.Read() )
{
  SegmentDbRecord record = new SegmentDbRecord();

  record.first_stop_id = dataReader.GetInt32(0);
  record.first_stopway = dataReader.GetString(1);
  record.first_stopway_X = dataReader.GetString(2);

  record.second_stop_id = dataReader.GetInt32(3);
  record.second_stopway = dataReader.GetString(4);
  record.second_stopway_X = dataReader.GetString(5);

  record.segment_start = Tools.timeToFloat((DateTime)dataReader.GetValue(6));
  record.segment_finish = Tools.timeToFloat((DateTime)dataReader.GetValue(7));

  record.stop1_long = dataReader.GetFloat(8);
  record.stop1_lat = dataReader.GetFloat(9);
  record.stop2_long = dataReader.GetFloat(10);
  record.stop2_lat = dataReader.GetFloat(11);

  record.max_speed = dataReader.GetInt32(12);
  record.avg_speed = dataReader.GetInt32(13);
  record.route_hnd = dataReader.GetInt32(14);
  record.seq_1 = dataReader.GetInt32(15);
  record.seq_2 = dataReader.GetInt32(16);
  record.route_name = dataReader.GetString(17);

  segmentData.AddFirst(record);

}

At this stage, I'm just saving the query's results inside a linked list. I'm pretty sure the crash happens during memory allocation but I know there is still plenty of memory left and the query is not returning such a large dataset. Running a simple loop allocating new "records" also crashes very fast. Do any of you know of a built-in protection in the ArcGIS runtime that could prevent me from allocating more than a certain amount of memory ?

Thank you !

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

美人如玉 2024-08-08 17:12:05

我找到的解决方案是在不同的线程中进行所有处理。 我的工具的结构方式是,按钮事件将命令发送到“作业处理程序”(让我们称之为它,我不会分享我不那么原始的内部类名),该命令立即执行它(因为没有其他工作已安排)。 我认为由于内存分配花费的时间太长,ArcGIS 认为 COM DLL 无响应,并且通过在没有任何指示的情况下简单地崩溃来处理这种情况。

感谢大家总是提供有用的答案。

The solution I found is to do all the processing in a different thread. The way my tool is structured, the button event was sending a command to a "Job handler" (let's call it that, I won't share my not-so-original internal class names) which was executing it right away (since no other work was scheduled). I think that since the memory allocation was taking too long, ArcGIS was considering the COM DLL as unresponsive and was handling the situation by simply crashing without any indication.

Thanks everyone for your always helpful answers.

樱花落人离去 2024-08-08 17:12:05

很久以前,我们的 Arc GIS 也遇到过类似的神秘崩溃问题。 我们最终发现在服务器端为Arc GIS 帐户启用了磁盘配额。 取消配额解决了这个问题。

如果其他方法不起作用,也许您可​​以尝试一下。

We had a similar mysterious crash issue with Arc GIS long time back. We eventually found that the disk quota was enabled in the server side, for the Arc GIS account. Removing the quota solved the issue.

Probably you can try that if anything else is not working.

傲影 2024-08-08 17:12:05

可能是数据转换问题。 以这一行为例:

record.max_speed = dataReader.GetInt32(12);
  • Is max_speed an int32?
  • 12位的字段是不是可以转成int32的值?

您可以做的就是注释掉所有分配值的行,查看它是否运行,然后一次添加一行,看看哪一行导致了错误。

编辑

根据评论看起来问题是由于使用 LinkedList 造成的。 为什么不直接使用列表呢?

It could be a data conversion problem. Take for example the line:

record.max_speed = dataReader.GetInt32(12);
  • Is max_speed an int32?
  • Is the field in position 12 a value that can be converted to int32?

What you could do is to comment out all lines that allocate values, see if it runs, then add the lines back one at a time and see which one causes the error.

EDIT

Based on the comment looks like the problem is due to use of LinkedList. Why not just use List?

淡笑忘祈一世凡恋 2024-08-08 17:12:05

ArcMap 悄悄地吞掉了用户添加组件的异常。 您可以捕获并处理代码中发生的任何异常。

一种简单的故障排除技术包括将整个代码块包装在类似以下内容中:

try {
    ... 
} catch (Exception ex) { 
    MessageBox.Show(ex.ToString());
    throw;
}

希望您会收到一条信息丰富的消息。

ArcMap quietly swallows exceptions from user-added components. It's up to you to trap and handle any exceptions that occur in your code.

A simple troubleshooting technique consists of wrapping the entire code block in something like the following:

try {
    ... 
} catch (Exception ex) { 
    MessageBox.Show(ex.ToString());
    throw;
}

Hopefully you will get an informative message.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文