如何在调试时可靠地获取Visual Basic .Net中的ComboBox.Text值?

时间:2014-03-28 02:36:39

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

AFAIK这应该是一个非常简单的任务,但经过两次不同的尝试后,我仍然无法验证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属性,这种方式在我的Watch Window中调试时有效,并且(希望)也可用作表达式I我的代码可以在任何地方使用吗?!我是否必须为所有表单元素的每个get / set / element成员组合创建一个新的唯一委托函数?请不要!

编辑(尝试将2个代码验证为线程安全): 经过进一步调查,我已多次验证我的代码示例在尝试2中确实有效,但在理解VS 2013调试器时必定会出现一些严重错误。如果监视窗口表达式失败的原因是由于交叉线程问题,那么如果调用我的线程安全getter,它们应该工作(毕竟,那些getter在运行时对其他线程运行良好 - 没有创建表单控件的时间)。那么调试器的线程有什么独特之处呢?他们不能使用我编写的那些线程安全函数?!解决这个问题确实是这个问题的答案。

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

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

1 个答案:

答案 0 :(得分:2)

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

来自Debug Multithreaded Applications in Visual Studio

  
    

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

  
相关问题