Arcgis Engine 异步任务的有趣设定

今天根据测试反馈的BUG,说数据导出成个人地理数据库的时候程序会直接死掉。像这种导出导入的需要长时间执行的任务,向来是异步执行的,于是我测试了一下同步执行,完美实现没有问题。

难道ArcGIS Engine不支持异步,也就是不支持多线程?不能呀,以前做了那么多项目,也没发现过AE不支持多线程的情况。然后我查了一下,ArcObjects(Arcgis Engine、Arcgis Desktop、Arcgis Server的核心库,以下简称AO)是单线程单元(Single-Threaded Apartment,SAT),也就是AO中的的所有对象都应该只与该进程内的对象通信。

在.Net Framework 4.0及之前,用多线程来异步还挺麻烦的,通常一个异步任务通常都是一个相对独立的代码块,很少会出现一个对象在自己不注意的情况下跨线程使用的情况,然后.Net 4.0出现了Task,.Net 4.5出现了async/await,异步变得非常简单,一不小心对象就跨线程使用了。实际上既然支持了async/await,.Net会自动完成信息的跨线程传递,在遇到简单任务,比如仅仅是对象的信息读取时,即使AO的对象都是单线程单元,跨线程是完全没有问题的,但是当遇到复杂任务,比如引起我程序崩溃的是在个人地理数据库中创建一个要素类,那就不行了。

在下面给出几种解决方法:

  1. 我目前用的,上面不是说读取自动传递过来的对象信息是没啥问题的嘛,可以根据读取到的信息,构建一个新对象,注意必须精细到简单类型,也就是值类型或者非托管类型,不然就有可能会失败。
  2. 主动线程间通信,注意这个时候也不能直接给AO的对象传过来,可以先给对象序列化,然后传过来之后再反序列化。

总而言之就是把之前对象的信息传过来但是不能有之前对象的引用。

嗯,这又是一个记录。

加载评论框需要翻墙