C#,Gmap.net:使用 Gmap.net 库在 google 地图上绘制 5 个标记时生成异常
C#,Gmap.net :Generating exception while plotting 5 markers on google map using Gmap.net liabrary
我正在使用 Gmap.net 库在 google 地图上通过三角算法进行计算后在特定的 let-long 处绘制标记,当我为两个标记工作时它工作正常但是当我试图绘制 5 个标记,它向我显示异常
An unhandled exception of type 'System.InvalidOperationException'
occurred in mscorlib.dll
Additional information: Collection was modified; enumeration operation
may not execute.
我在做什么,我已经为五个标记创建了 5 个线程,它们正在地图上绘制。
- 当标记正在绘制时,如果我做很多放大缩小
它显示异常。
- 绘图时我再次移动地图,它显示异常。
我无法弄清楚为什么 happening.even 它没有显示任何行号。这是错误的快照。
请帮忙。
编辑:这是在地图上绘制的代码,包括添加标记和路线,我对所有 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();
}
所以你提到你 运行 分开线程来添加标记和路线。这可能会导致线程问题。 UI 线程尝试绘制您的标记,因此遍历标记列表。当另一个线程将标记添加到当前正在绘制的标记集合中时,迭代器将变为无效,从而抛出异常。
解决方案:确保以 UI 同步方式添加标记。
作为验证上述假设的第一种简单方法,请尝试不使用线程的代码,然后 使用主线程来尝试您的线程。基本上最终的 AddMarker()
必须在主线程上发生。
编辑
您需要在 InvokeRequired
和 BeginInvoke
的帮助下应用 in this link 演示的同步。看看他们如何更新文本控件,一个 uni 元素作为 gmap 实例。为此,标记的实际添加必须在 action/delegate 内进行。让我们试着从那里开始,请让我们知道你有多远。
我正在使用 Gmap.net 库在 google 地图上通过三角算法进行计算后在特定的 let-long 处绘制标记,当我为两个标记工作时它工作正常但是当我试图绘制 5 个标记,它向我显示异常
An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll
Additional information: Collection was modified; enumeration operation may not execute.
我在做什么,我已经为五个标记创建了 5 个线程,它们正在地图上绘制。
- 当标记正在绘制时,如果我做很多放大缩小 它显示异常。
- 绘图时我再次移动地图,它显示异常。
我无法弄清楚为什么 happening.even 它没有显示任何行号。这是错误的快照。
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();
}
所以你提到你 运行 分开线程来添加标记和路线。这可能会导致线程问题。 UI 线程尝试绘制您的标记,因此遍历标记列表。当另一个线程将标记添加到当前正在绘制的标记集合中时,迭代器将变为无效,从而抛出异常。
解决方案:确保以 UI 同步方式添加标记。
作为验证上述假设的第一种简单方法,请尝试不使用线程的代码,然后 AddMarker()
必须在主线程上发生。
编辑
您需要在 InvokeRequired
和 BeginInvoke
的帮助下应用 in this link 演示的同步。看看他们如何更新文本控件,一个 uni 元素作为 gmap 实例。为此,标记的实际添加必须在 action/delegate 内进行。让我们试着从那里开始,请让我们知道你有多远。