AnsweredAssumed Answered

MapDocument and Threading

Question asked by gasparovic on Jan 28, 2019

I'm having problems with getting the mxd from the threaded function call, it's looks like it's an instance I cannot access.

 

My task is to loop through the mxd paths, open the mxd, loop the layers and re-point to designated datasources, loop the tables and re-point, save the mxd as another one.

 

Reason I'm trying to access the mxd created in the threaded process:

  • I have a batch script that is processing a lot of MXDs and there are mxds that simply crashes the whole process, bypassing the try: catch: blocks. Don't ask me why, but they fail to open in ArcMap as well. Not really my issue, all I want is to make sure it won't crash the process.

 

Why don't I put the whole process of opening the mxd and looping via datasources in the threaded call

  • I've noticed that once I create an mxd in the threaded call, I can list the layers, but the subsequent call to list the tableviews fails with the "'NoneType' object has no attribute '_arc_object'"
    So I suspect there is something behind the scenes in the MapDocument in arcpy that is not playing nice with the threading.
    If I do the same thing in the non-threaded script for a valid mxd it won't fail on list layer and subsequent list tables
    If I do the same thing in the threaded script for a valid mxd, it will fail on listing the tables. If I omit listing the layers, listing the tables will work. weird huh?

 

So what am I trying to do

  • I wanted to access the mxd in the threaded process so if it is to crash the process, it won't disrupt the main thread. If it opens ok, I want to access this thread's instance of MXD in the main thread. Is this possible? If so, how?
  • I'm also unable to provide a pointer only that I would be able to modify within the threaded process (via class with the Thread parent class)
  • I'm also unable to modify the global variable from within the threaded process.

 

One of the (and simplest) approaches I've done is the following, which returns whatever you see in the screenshot capture:

from multiprocessing.pool import ThreadPool
pool = ThreadPool(processes=1)
mxd = pool.apply(openMapDocument, (mxd_path,))

and...

def openMapDocument(mxd_path):
mxd = None
    try:
        mxd = arcpy.mapping.MapDocument(mxd_path)
return mxd

except BaseException as ex:
print 'Unable to open map document'
        raise

This will then fail on listing anything from the document with the AttributeError: 'NoneType' object has no attribute 'dataFrames' (similar to _arc_object)

Outcomes