Skip to content
August 2, 2006 / Steven Pousty

Help with Automation in C# and ArcMap

As you can see in the update to my previous post – testing my code with my coworkers revealed some “issues”. I have isolated the issue to be the fact that ArcMap and my C# code are running in seperate threads and so my call to get the datasets is happening before ArcMap has fully loaded the mxd.

I have a post open in the discussion forums if someone wants to help out (C’mon, you know you want the MVP points). But if you would rather post here I need some help on managing the threading between my C# code and ArcMap. I need a way to have my application block until the document is fully loaded.

I have googled around a bit but I am not even quite sure of the right terms to look for. Any help would be appreciated…


/Start arcmap
ArcMapDoc = new MxDocumentClass();
//Get a reference to the application
ArcMapApp = ArcMapDoc.Parent;
//I don't think I need to Show arcmap
ArcMapApp.Visible = true;
ArcMapApp.OpenDocument(file);  

//I NEED SOMETHING TO WAIT HERE UNTIL THE DOCUMENT IS LOADED
//OR I NEED TO PUT THE SUBSEQUENT CODE IN A CONSTRUCT THAT KNOW TO WAIT FOR THE DOCUMENT OPENED  EVENT FROM ARCMAP

ESRI.ArcGIS.Geodatabase.IEnumDataset datasets = ArcMapDoc.Datasets;
ESRI.ArcGIS.Geodatabase.IDataset dataset = datasets.Next();

UPDATE

So thanks to Tony the Air Quality Engineer at my firm we figured out a hack. I was looking into Automation and event firing and found at least one article. But then Tony came walking by and I remembered that he had done some C# work. We figured out a hack that does what I needed. Since this is in house code to relieve us of some of the mundane work, hacks are ok in my book. The title of the Document in arcmap is untitled until it finally loads the document. Here is the hack:

Boolean docLoaded = false;
while (!docLoaded) {
    if (ArcMapDoc.Title != "Untitled") {
        docLoaded = true;
    }
    Thread.Sleep(3000);
}

I will update the code in my previous post accordingly

And thanks to Brian Flood for helping out…

Advertisements

14 Comments

Leave a Comment
  1. Brian Flood / Aug 2 2006 2:12 pm

    hey Steve

    Why wouldn’t you just use IMapDocument so it runs completely in your process? It will be alot more efficient and it doesn’t have the overhead of an entire ArcMap process being started.

    that’s what I would use in this situation…

    cheers
    brian

  2. thesteve0 / Aug 2 2006 2:15 pm

    IMapDocument doesn’t give a handle to IDocumentDatasets which is the interface I am trying to get to. I can get from IMapDocument to MapDocument but MapDocument does not implement IDocumentDatasets, only MxDocument does.
    Thanks for the suggestion…

  3. Brian Flood / Aug 2 2006 2:26 pm

    ok, but can’t you get the datasets by just enumerating the layers?

    b

  4. thesteve0 / Aug 2 2006 3:04 pm

    Yeah you can but there are all the exceptional cases like group layers and duplicated data sets and multiple maps and tables. This interface makes things so nice… (well except for the automation piece)

  5. ccavin / Aug 3 2006 6:56 am

    I’m not sure when it gets fired (before or after load), but you might try listening for the IDocumentEvents.OpenDocument event.

  6. Brian Flood / Aug 3 2006 7:08 am

    glad you got a fix but I’m still sticking with the IMapDocument way, it’s a lot cleaner. Add in a little recursion code and the group layers would not be an issue.

    anyways, glad you got somethign working…

  7. thesteve0 / Aug 3 2006 9:50 am

    ccavin – yeah I thought of that but I was not sure how to capture that event when using automation. How does my C# code know when the event has happened in the other thread?

    Brian – I hear ya but I needed this to be finished. Perhaps we can get the good ppl at ESRI to implement IDocumentDatasets on MapDocument and then life would be so much better…

  8. Brian Flood / Aug 3 2006 11:58 am

    what’s your new email?

  9. thesteve0 / Aug 3 2006 12:06 pm

    find me at gmail with the name scitronpousty

  10. ccavin / Aug 4 2006 9:34 am

    Here is one solution for notifying your code when an event happens in a different thread, though I know there are more.

    Have a ManualResetEvent member variable initialized to not-set:
    ManualResetEvent m_documentLoadedEvent = new ManualResetEvent(false);

    Just after document creation (in StartArcMapProcessing), add:
    (ArcMapDoc as IDocumentEvents_Event).OpenDocument += new IDocumentEvents_OpenDocumentEventHandler(OnOpenDocument);

    Instead of the sleep loop, use:
    m_documentLoadedEvent.WaitOne();

    Add the following member method to handle the OpenDocument event:
    void OnOpenDocument()
    {
    m_documentLoadedEvent.Set();
    }

  11. ccavin / Aug 4 2006 9:40 am

    Oops. I forgot a couple of lines.
    In order for the solution to work for more than one mxd, you’ll have to add _documentLoadedEvent.Reset(); at the beginning of the for loop in StartArcMapProcessing.
    Just before QuitArcMap, you’ll want to add:
    (ArcMapDoc as IDocumentEvents_Event).OpenDocument -= new IDocumentEvents_OpenDocumentEventHandler(OnOpenDocument);

  12. thesteve0 / Aug 4 2006 10:36 am

    Thanks ccavin – you are too kind to share this. Do you know where I would go to read more about this? Is this is what is referred to as “sinking” an event?

  13. mnorm / Aug 10 2006 12:45 pm

    I hate to do this, but could you send me what you’ve got to date? I was contemplating the same thing you’ve started here, and it was very timely that I ran across your blog. Once I get up to speed, I am sure I will be of assistance. Not the best C# coder, but not the worst either.

  14. thesteve0 / Aug 10 2006 12:55 pm

    sent it let me know if you don’t receive it since gmail is wonky about sending zips

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: