【问题标题】:How can I reliably get ComboBox.Text value in Visual Basic .Net while debugging?调试时如何在 Visual Basic .Net 中可靠地获取 ComboBox.Text 值?
【发布时间】:2014-03-28 02:36:39
【问题描述】:

AFAIK 这应该是一个非常简单的任务,但是经过 2 次不同的尝试后,我仍然无法验证 Visual Basic .Net 4.5 中 ComboBox 的当前值。

我怎样才能可靠地得到它?下面详细介绍了我之前的 2 次尝试,希望您能告诉我我的错误在哪里。

尝试 1(a):

在 Visual Studio Express 2013 中调试时尝试从 Watch 窗口访问 MyComboBox.Text 属性。我没有检索 text 属性,而是在 Watch Window 中收到以下消息:

An exception 'Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException' occurred.

这似乎是“正常”行为,在 microsoft.com [1] 上的一篇有用文章中描述了解决方法。

尝试 1(b):

按照 [1] 中的描述添加 Control.CheckForIllegalCrossThreadCalls = False 行没有帮助。我将此行包含在我的表单代码的New() Sub 中,并通过将其作为表达式添加到监视窗口来验证Control.CheckForIllegalCrossThreadCalls 在运行时确实设置为False。行为没有变化,我收到了与上面 尝试 1 中列出的相同的错误消息。

尝试 2:

按照第一篇文章 [1],我将以下代码添加到我的表单模块中:

Delegate Function GetBoardTextCallback() As String
Private Function GetBoardText() As String
    If Me.BoardBox.InvokeRequired Then
        Dim d As New GetBoardTextCallback(AddressOf GetBoardText)
        Return Me.Invoke(d)
    Else
        Return Me.BoardBox.Text
    End If
End Function

现在在我的观察窗口中,当我添加 GetBoardText() 时,会有大约 5 秒的延迟,然后在值列中出现一条关于无法评估表达式的消息,然后在我点击表达式刷新后,我收到以下消息: Cannot evaluate expression because we are stopped in a place where garbage collection is impossible, possibly because the code of the current method may be optimized.

我是代表的新手,所以我怀疑我的实现有问题。我必须承认我有点困惑,为什么简单地读取表单元素的值需要如此复杂(即使视觉元素的单独线程的概念看起来很简单)。我怎样才能可靠地获取(更不用说设置!)Visual Basic .Net 中 ComboBox 的Text 属性,其方式在我的监视窗口中进行调试时工作,以及(希望)也作为我可以使用的表达式工作我的代码中的任何地方?!我是否必须为所有表单元素的每个 get/set/element 成员组合创建一个新的唯一委托函数?请不要!

编辑(尝试 2 代码验证为线程安全): 在进一步的调查中,我多次验证我在尝试 2 中的代码示例确实有效,但在我对 VS 2013 调试器的理解中肯定存在一些关键错误。如果 Watch Window 表达式失败的原因是由于跨线程问题,那么它们应该在调用我的线程安全 getter 时工作(毕竟,这些 getter 在运行时对其他线程工作得很好——没有创建表单控件的时间)。那么调试器的线程有什么独特之处,以至于它们不能使用我编写的那些线程安全函数?!解决这个问题确实是这个问题的答案。

编辑(调试器工具中的错误?): 此外,根据其他 MS 文档 [2],调试器中有用于调试多线程应用程序的工具。 然而所有个可用线程添加监视表达式Me.BoardBox.TextGetBoardText()都会产生相同的结果。这是 IMO 更多证据表明调试器访问线程内存或其进程存在一些奇怪/独特的情况。如果只是“调试器正在查看错误的线程”类型的问题,那么多线程调试选项应该已经修复了它。

[1]http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx [2]http://msdn.microsoft.com/en-us/library/ms164739.aspx

【问题讨论】:

  • 什么是组合框类型?下拉列表、组合或可编辑列表?
  • @AdamZuckerman DropDownStyle = 属性窗格中的 DropDownList。我在那里看不到任何其他属性来区分您正在谈论的选项。它是一个右侧有一个向下指向的黑色箭头的框,您单击框上的任意位置,然后下拉列表,您必须从中选择一项。选择该 1 项后,列表会“向上”返回,所选项目在组合框中显示为文本。希望这能回答您的问题。
  • @AdamZuckerman 对象类型肯定是ComboBox,而不是Listbox,如果这就是你的意思的话。
  • 我过去在使用 ComboBox.Text 时遇到过问题。我发现使用 ComboBox.SelectedItem.Text 效果更好。 (msdn.microsoft.com/en-us/library/…)。
  • @AdamZuckerman 你的意思是BoardBox.SelectedText

标签: .net vb.net winforms visual-studio delegates


【解决方案1】:

当您在跨线程调试时,您将无法在另一个线程上获取某些东西的值。您问题中显示的 Invoke 方法将允许您的代码从 ComboBox 获取值,但在调试时不适用。

来自Debug Multithreaded Applications in Visual Studio

调试具有用户界面的多线程应用程序可能特别困难。在这种情况下,您可能会考虑在第二台计算机上运行应用程序并使用远程调试。有关信息,请参阅Remote Debugging in Visual Studio

【讨论】:

  • 我想使用完全独立的计算机将是一种实现我正在寻找的方法,但我很难相信所有需要检查表单元素属性的 VB .Net 程序员都有除了每次编程时使用 2 台计算机之外别无选择。
  • 您正在进入多线程应用程序的世界。这是一个 Visual Studio 问题。它不特定于任何 .NET 语言。如果您的应用程序是单线程的,您就不会遇到这个问题。
  • 很酷,谢谢你 - 我有一个错误假设,即 VB 总是使用单独的线程来“拥有”或更新视觉元素,但听起来这个问题是我创建自定义线程的场景所独有的,它通常不会在其他情况下不会出现。
  • 单线程拥有UI的概念其实来源于Windows it's self。无论您使用哪种语言,VB、C#、C++,这都是正确的。您只能从创建 UI 元素的线程中触摸 UI。虽然你可以从不同的线程创建 UI,但它只会给你带来一个痛苦的世界;保持简单,只从单个线程创建或访问 UI。
  • @BradleyUffner 所以它是 .Net 编程中公认的设计范例,工作线程永远无法读取 WinForm 控件的属性?当然,在我的例子中,产生需要定期访问控制成员的工作线程是很常见的,因为它们在执行时控制属性在线程声明后更新。问题不是来自其他线程的太多访问,而是来自调试器工具的访问。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-12-05
  • 2018-03-23
  • 2011-08-04
  • 2013-03-07
  • 1970-01-01
  • 2013-04-23
  • 1970-01-01
相关资源
最近更新 更多