C#,Gmap.net:使用Gmap.net liabrary在谷歌地图上绘制5个标记时生成异常

时间:2017-05-04 11:55:55

标签: c# multithreading parallel-processing gmap.net

我正在使用Gmap.net库在三角测量算法在谷歌地图上进行计算后绘制标记,当我为两个标记工作时它的工作正常但是当我试图绘制5个标记时它正在显示我异常

  

类型'System.InvalidOperationException'的未处理异常   发生在mscorlib.dll

     

其他信息:收集已修改;枚举操作   可能无法执行。

我正在做什么,我为五个标记创建了5个线程,这些标记正在地图上绘制。

  1. 当标记正在进行绘图时,如果我进行大量放大缩小 它显示例外。
  2. 在绘图时我再次移动地图会显示异常。
  3. 我无法弄清楚为什么会发生这种情况。即使它没有向我显示任何行号。这是错误的快照。enter image description here 请帮忙。 编辑:这里是在地图上绘制的代码包括添加标记和路线,我使用相同的功能为所有5个标记与不同的标记和路线名称

    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()); }
    

    这就是调用不同线程/任务的方式(尝试两者)

      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()); }
    

    更改:以下是我所做的更改,添加了绘图功能(如上所述),对于临界区中的所有5个标记,仍然是相同的问题。

    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();
            } 
    

1 个答案:

答案 0 :(得分:1)

所以你提到你运行单独的线程来添加标记和路由。这可能导致线程问题。 UI线程尝试绘制标记,因此迭代标记列表。当另一个线程将标记添加到当前正在绘制的标记集合时,迭代器将变为无效,因此抛出异常。

解决方案:确保以UI同步方式添加标记。

作为验证上述假设的简单第一种方法,请尝试使用没有线程的代码,然后使用主线程read how to synchronize线程。基本上最终AddMarker()必须在主线程上发生。

修改 您需要在InvokeRequiredBeginInvoke的帮助下应用已展示in this link的同步。看看他们如何更新文本控件,作为gmap实例的uni元素。为此,工作实际添加标记必须在该动作/委托中进行。让我们试着从那里拿走它,让我们知道你有多远,请。