Collection was modified; enumeration operation may not execute

Topics: Windows Forms
Nov 26, 2010 at 4:12 PM
Edited Nov 26, 2010 at 4:22 PM

 

Hi, when we try to draw lines on map, the program throws InvalidOperationException from GMap.Net.WindowForms.GMapControl
My Code 
        public void Track(PointLatLng point, string terminalId)
        {
            _gr = new GMapRoute(_track[terminalId], terminalId);
            {
                _gr.Stroke = new Pen(Color.FromArgb(144, Color.Red))
                                {
                                    Width = 5,
                                    DashStyle = System.Drawing.Drawing2D.DashStyle.DashDot
                                };
            }

            _routes = new GMapOverlay(this, terminalId);
            Overlays.Add(_routes);
            _routes.Routes.Add(_gr);
        }

protected virtual void OnPaintEtc(Graphics g)
      {
#if !PocketPC
         g.SmoothingMode = SmoothingMode.HighQuality;
#endif
         foreach(GMapOverlay o in Overlays) //<-- Collection was modified; enumeration operation may not execute.
{ if(o.IsVisibile) { o.Render(g); } } ....

 

Nov 26, 2010 at 5:14 PM

i guess you add it in other thread?

Nov 27, 2010 at 4:12 AM

ramazanulucay,

Are you are calling your Track(...) function from the main (GUI) thread or from some other thread? I expect that the OnPaintEtc(...) function is called on the main thread, and will only fail due to the Overlays collection being updated if you did that from another thread. I am making some guesses here, but maybe it will help... 

Martin.

Nov 29, 2010 at 9:31 AM

hi;

there is one thread for socket connections and i catch the incoming data from the socket in an event with this thread, but i never update map in this event, i update map in main thread. Is it possible to  get a trace log or a trace file to find this error.

Ramazan ULUCAY

Nov 29, 2010 at 10:59 AM

hi again;

 

There is no problem when you do not change the map center and zoom value, but when you change them the program throw exception. Sometimes i use Track function and HoldScreen function after and after, first i call track and then HoldScreen. What is the deal with this HoldScreen ?? When i don't call this HoldScreen, there is no problem.

public HoldScreen(PointLatLng latlng)
{
	if (!Program.MapControls.CurrentViewArea.Contains(latlng))
    {
		MapControls.SetCenter(latlng);
    }
}

 

Ramazan ULUCAY

 

 

Nov 29, 2010 at 11:13 AM

from what thread do you call it?

Nov 29, 2010 at 1:05 PM

from main threat. The code is here;

void SocketConn_onDataReceviedNewPosition(Sockets.EventArgsReceiveGP e)
        {
            if (MapControls == null) return;
            if (!Program.TerminalList.ContainsKey(e.TerminalID)) return;
            var terminal = Program.TerminalList[e.TerminalID];
            var latlng = MapControls.ToPointLatLng(e.Latitude, e.Longitude);
            if (terminal.PropLeaveTrace == 1)
            {
                MapControls.TrackVehicle(latlng, e.TerminalID);
            }
            TerminalCommandListCtrl(e.TerminalID, Command.newPosition, "Position Update");
            if (terminal.PropHoldOnScreen == 1)
            {
                if (!MapControls.CurrentViewArea.Contains(latlng))
                {
                    MapControls.SetCenter(latlng);
                }
            }

            if (terminal.PropAlertSounds == 1)
            {
                Program.StreamPlayer(Properties.Resources.info);
            }

            Program.TerminalList[e.TerminalID].Latitude = e.Latitude;
            Program.TerminalList[e.TerminalID].Longitude = e.Longitude;
            Program.TerminalList[e.TerminalID].Direction = e.Direction;
            if (_near != null) { _near.RefreshList(); }
        }

Nov 29, 2010 at 1:14 PM

i doubt that onDataReceviedNewPosition is executed on main thread ;}

Nov 29, 2010 at 1:36 PM

Ok then, how can i call this onDataRecieved from the main thread, any suggestions?

Ramazan ULUCAY

Nov 29, 2010 at 1:42 PM

I change code, but I don't know how can i call from the main thread.

         for (int i = 0; i < Overlays.Count; i++)
         {
             GMapOverlay o = Overlays[i];
             if (o.IsVisibile)
             {
                 o.Render(g);
             }
         }

Nov 29, 2010 at 2:14 PM

You will need to use a delegate:)

 

Nov 29, 2010 at 2:32 PM
Edited Nov 29, 2010 at 2:33 PM

Thanks azlan, I am using delegate, but allways a solution does not in to mind :) 

Problem solved.
Ramazan