cooolseee 发表于 2016-7-18 17:48:49

关于CAD文档管理的问题

本帖最后由 cooolseee 于 2016-7-19 09:05 编辑

各位高手,大家好。我想实现一个功能,是新建一个dwg文件,然后根据要求绘制图形。一种图形绘制完成后,保存并该dwg文件,然后新建文件,再重复上述工作内容。
我遇到的问题是:
1、我采用了以下代码:

//新建一个文件,此函数在Tools类中
public static Document dwgCreat()
      {
            DocumentCollection docs = Application.DocumentManager;
            Document doc = docs.Add("acad.dwt");
            //docs.MdiActiveDocument = doc;
            return doc;
      }
#region 初始化绘图环境
                Document doc = Tools.dwgCreat();
                Database db = doc.Database;
                Editor ed = doc.Editor;
                DocumentLock docl= doc.LockDocument();
#endregion 初始化绘图环境
//省略绘图过程
db.SaveAs(pathDWG + "图纸" + i +".dwg", DwgVersion.Current);

i++

                try
                {
                  docl.Dispose();
                  doc.CloseAndDiscard();
                }
                catch { }

每次都会出现如下错误提示:
致命错误:Unhandled Access Violation Reading 0x7ede0474 Exception at 6209546eh

07/18/2016 at 17:08:55.360图形: Drawing1.dwg

请大侠帮助,这个问题已经困扰我很久了,不知道怎么优化

cooolseee 发表于 2016-7-19 08:14:27

请大侠指点

cooolseee 发表于 2016-7-19 08:56:14

本帖最后由 cooolseee 于 2016-7-19 08:58 编辑

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;

using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using DotNetARX;


namespace 工具
{
publicclass Tools
{
#region 新建dwg文档
      //
      public static Document dwgCreat()
      {
            DocumentCollection docs = Application.DocumentManager;
            Document doc = docs.Add("acad.dwt");
            //docs.MdiActiveDocument = doc;
            return doc;
      }
      #endregion 新建dwg文档

}

public class 测试
{

      public void AAA()
      {

            for (int i = 0; i < 100; )
            {
                Circle cir = new Circle();
                cir.Center = new Point3d(0, 0, 0);
                cir.Radius = 10;

                #region 初始化绘图环境
                DocumentCollection docs = Application.DocumentManager;
                Document doc = Tools.dwgCreat();
                Database db = doc.Database;
                Editor ed = doc.Editor;
                DocumentLock docl = doc.LockDocument();//这句要不要
                #endregion 初始化绘图环境
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                  db.AddToModelSpace(cir);
                  trans.Commit();
                }
                if (docs.MdiActiveDocument != doc)
                  docs.MdiActiveDocument = doc;
                db.SaveAs("D:\\DWG\\" + i+ ".dwg", DwgVersion.AC1800);
                doc.CloseAndDiscard();
                i++;
            }

      }
}
}
上面的代码不确定锁定文档需不需要,如果需要,没有解锁文档对不对,请高手指点。测试没什么问题,就是用同样的原理,在我的程序中, 就会出现1楼描述的问题

cooolseee 发表于 2016-7-19 12:06:44

我测试了一下,通过DocumentCollection的ADD方式新建dwg文件,直接就是当前文档,不知道对不对,请高手指点

epwt 发表于 2016-7-19 20:39:21

本帖最后由 epwt 于 2016-7-19 20:41 编辑

1.在你不进行其它操作时,通过DocumentCollection的ADD方式新建dwg文件,就是最上层文档,因为会一层一层覆盖,你最新创建的在最上层
2.给你的Document对象加上锁,而且记得自动释放,你的代码改了下,就是加上了加锁那段,可以正确运行,就是测试的时候先把那100改成1吧,不然闪屏的关不住呀~
      public void AAA()
      {
            for (int i = 0; i < 1; )
            {
                Circle cir = new Circle();
                cir.Center = new Point3d(0, 0, 0);
                cir.Radius = 10;

                #region 初始化绘图环境
                DocumentCollection docs = Application.DocumentManager;
                Document doc = dwgCreat();
                Database db = doc.Database;
                Editor ed = doc.Editor;
             using (DocumentLock docLock = doc.LockDocument())
                {
                  //DocumentLock docl = doc.LockDocument();//这句要不要
                #endregion 初始化绘图环境
                  using (Transaction trans = db.TransactionManager.StartTransaction())
                  {
                        db.AddToModelSpace(cir);
                        trans.Commit();
                  }
                  if (docs.MdiActiveDocument != doc)
                        docs.MdiActiveDocument = doc;
                  db.SaveAs("D:\\DWG\\" + i + ".dwg", DwgVersion.Current);
                }
                doc.CloseAndDiscard();
                i++;
            }

      }

cooolseee 发表于 2016-7-20 09:03:09

epwt 发表于 2016-7-19 20:39 static/image/common/back.gif
1.在你不进行其它操作时,通过DocumentCollection的ADD方式新建dwg文件,就是最上层文档,因为会一层一层覆 ...

我的那个代码运行没什么问题,保存的文件从0-99然后自动停止。我现在有2个问题很疑惑:
1、通过DocumentCollection的ADD方式新建dwg文件,是不是当前文档,如果是,问什么在当前文档要加锁。如果不是,我测试的时候,明明看见docs.MdiActiveDocument的name属性和doc的name是一样的。
2、加锁后的文档,我画图结束了,文档都关闭了,还用不用解锁。我的那段代码是加锁了,没解锁,然后运行正常。
----------------------------------------------------------------------------------------
另外,用相同的原理,在我的代码中,每次生成第3个dwg文件,就会出现一个异常警告,然后,图纸可以继续按程序设定的顺序继续绘图,结果是正确的,就是老出现异常,感觉不爽,画图完毕,CAD会出现错误提示,得关闭。

epwt 发表于 2016-7-21 19:58:19

关于加锁的问题,我曾经也问过我的前辈,但是并没有得到确切的回答,所以就养成了一个经验写法,每次对数据库操作的时候都给文档加上锁。
第一个问题,我的理解是,创建的文档虽然是当前文档,但是它并不存在于物理磁盘中,而只存在于内存中,加锁是为了把这一块的内存锁定,防止冲突。这就验证了加锁的一个条件:访问已调入的文档而不是当前文档时,需要对文档加锁。我认为新建的这个文档是调入的文档,而非实际意义的当前文档。

第二个问题,画图结束后,是需要解锁的。我加的代码使用了using在调用结束后是会自动释放的。关于你没解锁运行正常,我认为这可能加完锁绘制完毕,你就把文档关了,并没有对文档继续操作,但你加锁的这块内存空间仍然处于占有状态,并没有释放。

只是发表一下个人看法,因为并没有找到官方的资料来彻底弄清楚这个问题。希望借你这篇帖子,也能引起更多朋友的注意,有大牛出来科普这个问题吧。

CAD二次开发先开始你觉得很神奇很简单,越往后开始钻研底层的问题,你会觉得CAD二次开发的API其实很深~有些问题我们可以暂时解决,但是可能过了很久,我能才能了解产生问题深层的原因。加油吧!共勉~

cooolseee 发表于 2016-7-22 08:13:04

epwt 发表于 2016-7-21 19:58 static/image/common/back.gif
关于加锁的问题,我曾经也问过我的前辈,但是并没有得到确切的回答,所以就养成了一个经验写法,每次对数据 ...

谢谢你的回复,有些东西你考虑的还是比较的深,我因为不是搞软件的,只是工作中需要,才搞这个二次开发。希望能得到像你这样大牛的指点。谢谢!
页: [1]
查看完整版本: 关于CAD文档管理的问题