gpt4 book ai didi

c# - 为什么通过循环第二次删除列表框项会崩溃?

转载 作者:行者123 更新时间:2023-12-03 15:48:44 26 4
gpt4 key购买 nike

这是一个持续存在的问题;在下面的代码中,旧代码(也失败了)被注释掉了。不过,新代码的行为方式相同:

private void UpdateGUIAfterTableSend(String listboxVal)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend");
try
{
//listBoxWork.DataSource = null; // <= This (at one time, anyway) seemed necessary to circumvent "Value does not fall within the expected range"
//// Failing ignominiously; question at https://stackoverflow.com/questions/28439941/why-is-this-array-list-removal-code-failing
//for (int i = listBoxWork.Items.Count - 1; i >= 0; --i) // try a foreach instead?
//{
// if (listBoxWork.Items[i].ToString().Contains(listboxVal))
// {
// listBoxWork.Items.RemoveAt(i);
// }
//}
BindingSource bs = listBoxWork.DataSource as BindingSource;
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend#2");
for (int i = bs.Count - 1; i >= 0; --i)
{
if (bs[i].ToString().Contains(listboxVal))
{
bs.RemoveAt(i);
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend#3");
}
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format("{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From frmMain.UpdateGUIAfterTableSend: {0}", msgInnerExAndStackTrace));
}
}

似乎第二次通过for循环,应用程序突然崩溃了。我这样说是因为日志文件显示“Reached frmMain.UpdateGUIAfterTableSend#3”,但不是来自 catch block 的日志消息。所以它必须在四个循环的第二次迭代中崩溃(在再次记录“Reached frmMain.UpdateGUIAfterTableSend#3”之前)。所以一旦它崩溃了,那就晚安,艾琳:它崩溃得如此之快,它甚至没有记录 catch block 的日志消息。还是有其他解释?

但更重要的是:为什么第二次检查“包含”或第二次尝试删除(在我的测试用例中不应该发生,列表框只有一个项目)会引爆一个代码狂野的核装置?

这是崩溃后的最后一个日志文件:
Date: 2/11/2015 12:45:34 PM
Message: Reached frmMain.UpdateGUIAfterTableSend

Date: 2/11/2015 12:45:34 PM
Message: Reached frmMain.UpdateGUIAfterTableSend#2

Date: 2/11/2015 12:45:34 PM
Message: Reached frmMain.UpdateGUIAfterTableSend#3

Date: 2/11/2015 12:45:34 PM
Message: From application-wide exception handler: System.InvalidOperationException: InvalidOperationException
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at HHS.frmMain.SendDeliveries()
at HHS.frmMain.menuItemSEND_Deliveries_Click(Object sender, EventArgs e)
at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
at System.Windows.Forms.Menu.ProcessMnuProc(Control ctlThis, WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at HHS.Program.Main()

更新

我在“RemoveAt”行之前添加了另一个日志消息,并得到了我所期望的:
Date: 2/11/2015 1:36:53 PM
Message: About to remove listbox value DSD_3_20150209151047000 at index 0

...但在那之后它立即崩溃,所以 Rake36 一定是对的。

更新 2

我有点相信这会奏效:
private void UpdateGUIAfterTableSend(String listboxVal)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend");
try
{
ExceptionLoggingService.Instance.WriteLog(String.Format("About to remove listbox value {0}", listboxVal));
listBoxWork.Items.RemoveAt(listBoxWork.Items.IndexOf(listboxVal));
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format("{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From frmMain.UpdateGUIAfterTableSend: {0}", msgInnerExAndStackTrace));
}
}

...但是当我听到“砰!”的声音时,我的希望破灭了。然后在日志文件中搜索:
Message: About to remove listbox value DSD_3_20150209151047000

Date: 2/11/2015 1:58:18 PM
Message: From frmMain.UpdateGUIAfterTableSend: Specified argument was out of the range of valid values.; Inner Ex: ; Stack Trace: at System.Collections.ArrayList.RemoveAt(Int32 index)
at System.Windows.Forms.ListBox.ObjectCollection.RemoveAt(Int32 index)
at HHS.frmMain.UpdateGUIAfterTableSend(String listboxVal)
at HHS.frmMain.SendDeliveries()
at HHS.frmMain.menuItemSEND_Deliveries_Click(Object sender, EventArgs e)
at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
at System.Windows.Forms.Menu.ProcessMnuProc(Control ctlThis, WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at HHS.Program.Main()


Date: 2/11/2015 1:58:19 PM
Message: From application-wide exception handler: System.InvalidOperationException: InvalidOperationException
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at HHS.frmMain.SendDeliveries()
at HHS.frmMain.menuItemSEND_Deliveries_Click(Object sender, EventArgs e)
at System.Windows.Forms.MenuItem.OnClick(EventArgs e)
at System.Windows.Forms.Menu.ProcessMnuProc(Control ctlThis, WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Form.WnProc(WM wm, Int32 wParam, Int32 lParam)
at System.Windows.Forms.Control._InternalWnProc(WM wm, Int32 wParam, Int32 lParam)
at Microsoft.AGL.Forms.EVL.EnterMainLoop(IntPtr hwnMain)
at System.Windows.Forms.Application.Run(Form fm)
at HHS.Program.Main()

我什至在“RemoveAt”行之前添加了这个:
listBoxWork.DataSource = null;

......但它没有任何区别。

更新 3

这(受 Ravi M Patel 启发)也崩溃了:
private void UpdateGUIAfterTableSend(String listboxVal)
{
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend");
try
{
BindingSource bs = new BindingSource();
bs.DataSource = listBoxWork.DataSource;
for (int i = bs.Count - 1; i >= 0; i--)
{
if (bs[i].ToString().Contains(listboxVal))
{
ExceptionLoggingService.Instance.WriteLog(String.Format("About to remove listbox value {0} at index {1}", listboxVal, i));
bs.RemoveAt(i);
ExceptionLoggingService.Instance.WriteLog("Reached frmMain.UpdateGUIAfterTableSend#3");
}
}
}
catch (Exception ex)
{
String msgInnerExAndStackTrace = String.Format("{0}; Inner Ex: {1}; Stack Trace: {2}", ex.Message, ex.InnerException, ex.StackTrace);
ExceptionLoggingService.Instance.WriteLog(String.Format("From frmMain.UpdateGUIAfterTableSend: {0}", msgInnerExAndStackTrace));
}
}

...并且日志文件的(相关)内容是:
Date: 2/11/2015 2:09:59 PM
Message: About to remove listbox value DSD_3_20150209151047000 at index 0

Date: 2/11/2015 2:09:59 PM
Message: Reached frmMain.UpdateGUIAfterTableSend#3

Date: 2/11/2015 2:09:59 PM
Message: From application-wide exception handler: System.InvalidOperationException: InvalidOperationException
at System.Collections.ArrayList.ArrayListEnumeratorSimple.MoveNext()
at HHS.frmMain.SendDeliveries()

更新 4

有关真正的修复,请参阅 How can I remove more than one item from a listbox?

最佳答案

异常来自与您显示的逻辑完全不同的地方。触发的是应用程序范围的异常处理程序,而不是创建跟踪“From frmMain.UpdateGUIAfterTableSend”的异常处理程序。异常很可能是因为绑定(bind)有副作用。查看绑定(bind)源和附加到它的事件。
还要在删除后添加跟踪,以便您可以看到删除确实发生或使用调试器。您的更新 3 显示删除确实发生了。

在 SendDeliveries 中添加更多跟踪。你的问题在那里

关于c# - 为什么通过循环第二次删除列表框项会崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28461319/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com