简体   繁体   中英

C#,Gmap.net :Generating exception while plotting 5 markers on google map using Gmap.net liabrary

i am using Gmap.net library to plot markers at a particular let-long coming after calculation made by triangulation algo on google maps,when i worked for two markers its works fine but when i tries to plot 5 markers its is showing me exception

An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll

Additional information: Collection was modified; enumeration operation may not execute.

what i am doing ,i have created 5 threads for five markers ,which are plotting on the map.

  1. while markers are getting plotting ,if i do lots of zoom in zoom out it show exception.
  2. while plotting i move the map again it show exception.

i am unable to figure out why it is happening.even it is not showing me any line no. here is the snapshot of error. 在此处输入图片说明 please help. EDIT: here is the code to plot on map includes adding markers and routes ,i have use same function for all 5 markers with different marker and routes name

void plot5(double temp_lat5, double temp_long5, string temp_date5, string temp_time5, string temp_bty_value5)
        {

                try
                {

                    //GMapMarker marker5 = new GMarkerGoogle(new PointLatLng(temp_lat5, temp_long5), GMarkerGoogleType.lightblue);
                    GMapMarker marker5 = new GMarkerGoogle(new PointLatLng(temp_lat5, temp_long5), new Bitmap(Properties.Resources.image12));
                    gmap.Overlays.Add(markers5);   // overlay added
                    Thread.Sleep(100);
                    markers5.Markers.Add(marker5);  //marker added 
                    marker5.ToolTipText = "AT CARD 05" + "\n" + "HIGH PRIORITY" + "\n" + temp_date5 + "\n" + temp_time5 + "\n" + temp_bty_value5 + "%"; //text to be displayed on the marker
                                                                                                                                                        // text properties
                    marker5.ToolTip.Fill = Brushes.Bisque;
                    marker5.ToolTip.Foreground = Brushes.White;
                    marker5.ToolTip.Stroke = Pens.Black;
                    marker5.ToolTip.TextPadding = new Size(20, 20);



                    if (count5 != 0)
                    {
                        List<PointLatLng> points5 = new List<PointLatLng>();
                        points5.Add(new PointLatLng(temp_lat5, temp_long5));
                        points5.Add(new PointLatLng(lat5, long5));
                        GMapRoute route5 = new GMapRoute(points5, "walk05");
                        route5.Stroke = new Pen(Color.Aquamarine, 3);

                        gmap.Overlays.Add(routes5); // first overlays then routes or markers
                        routes5.Routes.Add(route5);
                    }
                    count5++;
                    lat5 = temp_lat5;
                    long5 = temp_long5;
                }
                catch (Exception hy)
                { MessageBox.Show(hy.ToString()); }

that's how m calling the different threads /tasks(tried with both)

  private   void button1_Click(object sender, EventArgs e)// Creating and startting threads for 5 diffrent at cards
        {
            try
            {
                if (m_parentform.update_flag_data == 1)
                {
                    if (list_at.Count != 0)
                    {
                        for (int y = 0; y < list_at.Count; y++)
                        {
                            for (int x = 0; x < m_parentform.at_cards_serials.Count; x++)
                            {
                                if (list_at[y] == m_parentform.at_cards_serials[x])

                                {
                                    try
                                    {
                                        int index = m_parentform.at_cards_serials.IndexOf(m_parentform.at_cards_serials[x]);
                                        switch (index)
                                        {
                                            case 0:
                                                {
                                                    Task lat_longthread1 = new Task(new System.Action(custom01));
                                                    lat_longthread1.Start();
                                                   // await lat_longthread1;

                                                   // Thread lat_longthread1 = new Thread(new ThreadStart(custom01));
                                                   // lat_longthread1.Start();

                                                    break;
                                                }

                                            case 1:
                                                {
                                                    Task lat_longthread2 = new Task(new System.Action(custom02));
                                                    lat_longthread2.Start();
                                                   // await lat_longthread2;
                                                    //Thread lat_longthread2 = new Thread(new ThreadStart(custom02));
                                                    //lat_longthread2.Start();
                                                    break;
                                                }

                                            case 2:
                                                {
                                                    Task lat_longthread3 = new Task(new System.Action(custom03));
                                                    lat_longthread3.Start();
                                                  //  await lat_longthread3;
                                                    //Thread lat_longthread3 = new Thread(new ThreadStart(custom03));
                                                    //lat_longthread3.Start();
                                                    break;
                                                }
                                            case 3:
                                                {
                                                    Task lat_longthread4 = new Task(new System.Action(custom04));
                                                    lat_longthread4.Start();
                                                   // await lat_longthread4;
                                                    //Thread lat_longthread4 = new Thread(new ThreadStart(custom04));
                                                    //lat_longthread4.Start();
                                                    break;
                                                }
                                            case 4:
                                                {
                                                    Task lat_longthread5 = new Task(new System.Action(custom05));
                                                    lat_longthread5.Start();
                                                  //  await lat_longthread5;
                                                    //Thread lat_longthread5 = new Thread(new ThreadStart(custom05));
                                                    //lat_longthread5.Start();
                                                    break;
                                                }
                                        }

                                    }
                                    catch (Exception ty)
                                    { MessageBox.Show(ty.ToString()); }
                                }
                            }
                        }
                    }
                    else
                    { MessageBox.Show("select at cards to plot"); }

                }
                else
                { MessageBox.Show("flag is not updated"); }
            }
            catch (Exception jo)
            { MessageBox.Show(jo.ToString()); }

CHANGES:following is the change i made ,added the plot function(described above),for all 5 markers in critical section ,still issue is same.

void marker_selection(int plot_no)
        {
            mut2.WaitOne();
            int marker_no = plot_no;
            switch (marker_no)
                {

                case 1:
                    {
                        plot(one1, two1, date[0], time[0], bty[0]);  // not sending bty part 2 which indicates milli volt value 
                        break;
                    }
               case 2:
                    {
                        plot2(one2, two2, date2[0], time2[0], bty2[0]);  // sending only part one of bty
                        break;
                    }
                case 3:
                    {
                        plot3(one3, two3, date3[0], time3[0], bty3[0]);  // sending only part one of bty
                        break;
                    }
                case 4:
                    {
                        plot4(one4, two4, date4[0], time4[0], bty4[0]);  // sending only part one of bty
                        break;
                    }
                case 5:
                    {
                        plot5(one5, two5, date5[0], time5[0], bty5[0]);  // sending only part one of bty
                        break;
                    }
            }
            mut2.ReleaseMutex();
        } 

So you mentioned you run separate threads to add the markers and routes. This can result in threading issues. The UI thread tries to draw your markers and therefore iterates over the lists of markers. When another thread adds a marker to the collection of markers that are being currently drawn, then the iterator becomes invalid, hence the exception is thrown.

The solution: Make sure the adding of the markers happens in an UI synchronized manner.

As a simple first approach to validate the assumption above try your code without threading and then read how to synchronize your threads with the main thread. Basically the eventual AddMarker() has to happen on the main thread.

Edit You'll need to apply synchronisation as demonstrated in this link with the help of InvokeRequired and BeginInvoke . Have a look how they update the text control, an uni element as the gmap instance. For this then to work the actual add of the markers has to happen within that action/delegate. Let's try to take it from there and let us know how far you get, please.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM