Select to view content in your preferred language

Working with a Map Document causes my program to freeze.

672
4
02-16-2011 09:31 AM
ThomasBates
Deactivated User
First off, I'm using Delphi 2007 and ArcObjects 9.3.

My application has a bit of start-up code that loads a map document, updates the feature layers to make sure they are looking at the correct File GeoDatabase, and saves the map document again.  Then, the updated map document gets loaded into the map control and everything looks beautiful.

THE CATCH is that this works sometimes, but not all the time.  When I run it from the Delphi IDE, it works about 99% of the time.  When I run the executable file directly, it fails about 90% of the time.

When it fails, it doesn't throw an exception or anything, it just freezes.  And it freezes in random places:  sometimes in the middle of the "Save" call, the "Close" call, the "Get_UsesRelativePaths" call, and sometimes while leaving the method that contains the ArcObjects calls.  And sometimes not at all.

I created a little stand-alone application with just the bit of start-up code, and it shows the same behaviour.  I then started removing bits to try to isolate the cause. 

I started by commenting out the code that modifies the feature layers.  It still froze.  Then I continued until the code was only opening the MapDocument, accessing the Map and then closing the document again.  It still froze.  I then commented out the Get_Map call and after repeated tries I could not get it to freeze when it was just opening and closing the map document.

Here is the method that I'm working with:

procedure TMain.UpdateMapDocument(AMapDocumentFileName, AWorkspacePath: string);
var
  mapDocument:      IMapDocument;
  isMapDocument:    WordBool;
  map:              IMap;
  useRelativePaths: WordBool;
begin
  Status('Updating Map Document ...');

  if FileExists(AMapDocumentFileName) and DirectoryExists(AWorkspacePath) then
  begin

    Status('Creating Map Document');
    mapDocument := CoMapDocument.Create as IMapDocument;

    Status('Testting Map Document');
    mapDocument.Get_IsMapDocument(AMapDocumentFileName, isMapDocument);
    if isMapDocument then
    begin
      Status('Opening Map Document');
      mapDocument.Open(AMapDocumentFileName, '');

      Status('Opening Map');
      mapDocument.Get_Map(0, map);

{
      //  Status('Updating Feature Layer Connections');
      //  UpdateFeatureLayerConnections(AWorkspacePath, map);

      Status('Saving Map');
      mapDocument.ReplaceContents(map as IMxdContents);

      Status('Getting Relative Units');
      mapDocument.Get_UsesRelativePaths(useRelativePaths);

      Status('Saving Map Document');
      mapDocument.Save(useRelativePaths, False);
}

      Status('Closing Map Document');
      mapDocument.Close;
    end;
  end;

  Status('... Updated Map Document');
end;


I've also attached the whole little test project.

When it works, it works exactly as expected so it seems that I'm doing this correctly.

I'm hoping someone can see something that I'm doing wrong that may be causing the freezing, or that someone has seen this freezing before and knows a work-around to avoid it.

Thanks,

Thomas Bates.
0 Kudos
4 Replies
KingsleyPayne
Deactivated User
The freezing sounds very much like a threading deadlock of sorts. Just out of curiosity, what happens if you remove the Application.ProcessMessages from your Status() procedure? Alternatively comment out all code in Status() and see if anything changes.

I'm not sure if you have the option to compile to x64 in Delphi, but in .NET we've seen some pretty erratic behavior when forgetting to specify an x86 target platform.

You may find this of interest:

Programming with ArcObjects 9.3 in Delphi 7, 2005, 2006, 2007, and 2009
http://arcscripts.esri.com/details.asp?dbid=14204
0 Kudos
ThomasBates
Deactivated User
Kingsley, thank you for your reply.

I agree that it smells like a threading deadlock.  However, Since I'm not doing any threading in this process, if it is a threading issue it must be internal to the ArcObject calls.  I know that it's possible that what I'm doing outside of the library calls can affect what happens inside, but I don't know in what way.  Partly that's what I was hoping someone could tell me.

About the Status() call, I initially was just setting the lblStatus.Caption property, but the form window didn't change until the whole process was finished and it said "Done."  Calling ProcessMessages allows the form to refresh and show the latest status text that was sent to it.

I tried your suggestion and commented out the internals of Status(), and it still freezes, only it won't tell me where.

Your question about the target platform got me wondering.  It's definitely x86.  I've been running it on Windows 7, so I thought I would try it on an XP box that I had available and I could not get it to freeze on the XP box.  I then had a few of my colleagues try it on their Windows 7 computers and some could get it to freeze and some could not.  I'm trying to identify patterns but I'm not finding anything yet.
0 Kudos
KingsleyPayne
Deactivated User
Does the problem occur with any map document, or are you always testing using the same Mxd?
0 Kudos
ThomasBates
Deactivated User
We have three Mxd files that I've been testing with and they all do the same thing.

Also, thanks for the link.  I've been going through the document and I don't know yet if anything in it will help with this immediate problem, but it will definitely help in general.
0 Kudos