6 Replies Latest reply on Jul 10, 2013 12:37 AM by MBranscomb-esristaff

    Graphics Layer inaccessible by background thread

    dipinbehl
      Hi All,

      I am using ArcGis API for WPF in a desktop based application to show locations, route for the stops on a 2D Map.
      A background thread fetches the locations (along with lat-long) from a WCF service. Then these locations are displayed on the Map as TextSymbol(s) on a GraphicLayer.
      Then another background thread calls a WCF RESTfull resource to find route for the locations (stops). This call returns me a route which i am trying to display on the map using another GraphicLayer using 'Add' method of the 'Graphics' property of the layer. Whenever i try to do so, i get an exception 'The calling thread cannot access this object because a different thread owns it.'
      I have tried to use Dispatcher object for the screen, the map object, the graphics layer but none seems to work for me.
        • Re: Graphics Layer inaccessible by background thread
          lcress-esristaff

          I have tried to use Dispatcher object for the screen, the map object, the graphics layer but none seems to work for me.


          Can you post the code that you are using to accomplish this?  What error do you get when you attempt to use the Dispatcher?
          • Re: Graphics Layer inaccessible by background thread
            AGoyal-esristaff
            Can you post the code that you are using to accomplish this?  What error do you get when you attempt to use the Dispatcher?


            I am getting similar error on my WPF application. Here is the code I am using-

            BackgroundWorker worker = new BackgroundWorker();
                                    worker.WorkerSupportsCancellation = true;
                                    //this is where the long running process should go
                                    worker.DoWork += (o, ea) =>
                                    {
                                        ea.Result = ReadShapeFileAsGraphics(droppedFilePaths[0]);
                                    };
                                    worker.RunWorkerCompleted += (o, ea) =>
                                    {
                                        IEnumerable<Graphic> graphics = ea.Result as IEnumerable<Graphic>;
                                        Dispatcher.CurrentDispatcher.Invoke((System.Action)(() =>
                                            {
                                                if (graphics.Count() > 0)
                                                    foreach (Graphic g in graphics)
                                                        GraphicLayer.GraphicsSource = graphics;

                                            }));
                                      
                                        //work has completed. you can now interact with the UI
                                        IsBusy = false;
                                    };
                                    //set the IsBusy before you start the thread
                                    IsBusy = true;
                                    worker.RunWorkerAsync();

            Thanks

            Apurva
            • Re: Graphics Layer inaccessible by background thread
              lcress-esristaff
              There are two issues here:

                                                  if (graphics.Count() > 0)
                                                      foreach (Graphic g in graphics)
                                                          GraphicLayer.GraphicsSource = graphics;


              This should be:
                                                  if (graphics.Count() > 0)
                                                      GraphicLayer.GraphicsSource = graphics;


              Secondly, and more importantly:

                                          Dispatcher.CurrentDispatcher.Invoke((System.Action)(() =>


              ...should be:

                                          Dispatcher.CurrentDispatcher.Invoke((System.Action)((graphics) =>
              • Re: Graphics Layer inaccessible by background thread
                brysageek
                Isn't the System.Action Anonymous and takes 0 args?

                would we have to create a new delegate with a Graphic set as one of the args....

                ??? I have been trying to get this to work for days now and still can't seem to get this thing going :(
                • Re: Graphics Layer inaccessible by background thread
                  lcress-esristaff
                  Isn't the System.Action Anonymous and takes 0 args?

                  would we have to create a new delegate with a Graphic set as one of the args....

                  ??? I have been trying to get this to work for days now and still can't seem to get this thing going :(


                  System.Action is anonymous in this example, but it can take an argument (or more than one, if needed; see the link), so it doesn't need to have a delegate.
                  • Re: Graphics Layer inaccessible by background thread
                    MBranscomb-esristaff
                    Hi,

                    I haven't had a chance to read the whole thread here - but you might want to take a look at the synchronization context info in http://forums.arcgis.com/threads/60409-Is-it-possible-to-edit-file-gdb-feature-classes-from-Windows-Service.

                    Cheers

                    Mike