[GIS] Accessing ArcGIS layers from separate thread using ArcGIS Engine

arcgis-9.3arcgis-enginearcobjectsmultithreading

I've got an ArcEngine application, referencing a MXD for it's data (and map display). I'm running a query against all layers, so can take quite some time.

I would normally run the query in a separate thread, which would allow me to return the results as they come in for each layer, rather than wait till all are layers are queried, then return a giant result set.

The limitation however is that I can't access any of the existing ArcObjects in my second thread, due to the STA threading model of ArcObjects.

The only way around it at this stage, appears to be to re-create my data environment from scratch in the second thread, simply for querying. The problem with this approach is that the layers have joins and attribute queries against them. For a number of reasons, it's just not a simply exercise to go this route.

I've looked at the IXMLSerialize interface, hoping to find some object, which would allow me to bridge between threads, which I could deserialize/serialize, but nothing sprang out to me.

Any other ideas?

UPDATE:
Because it was so important that I query against the layers, not the datasource, at this point, I save the search layers to .lyr files, then in my second thread, load them using the ILayerFile interface. This then gives me access to the layers with joins/relates/definition queries intact. The problem at this stage however, is that the ILayerFile.Layer call is very slow. So am looking for a way to speed that up. The threaded search does however perform wonderfully, and has improved the UI greatly!

Best Answer

Multithreading with ArcObject is a complex subject which I have reported to Esri, with no response yet. However, I can tell you a few things which I learned while doing this:

  1. Do not share any COM object across threads, this can degrade the performance.
  2. As explained in examples, if you want to anything pass it in strings not in heavy objects.
  3. Do everything from scratch, open workspace, open featureclass and query. Don't try to play with this. Because some of the objects are singleton like SDEWorkspaceFactory, opening featureclass again won't create a new object and you will observe that it takes less time as you start recreating it.
  4. Try to release objects mostly cursors and row buffers etc.

I am still facing some terrible issues like "Memory could not be read or write" or "AccessviolationException" while achieving multithreading with ArcObject on SDE DataSource. So I had to introduce locking mechanism to get rid of these errors. But that is not a correct solution to do so I think, because there is some cost involved in doing so and hence degrades performance.

Related Question