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.Text
和GetBoardText()
都会产生相同的结果。这更有证据表明,调试器访问线程内存或它的进程有一些奇怪/独特的东西。如果它只是一个"调试器正在查看错误的线程"类型问题,然后多线程调试选项应该修复它。
[1] http://msdn.microsoft.com/en-us/library/ms171728(VS.80).aspx [2] http://msdn.microsoft.com/en-us/library/ms164739.aspx
答案 0 :(得分:2)
当您跨线程调试时,您将无法在另一个线程上获取某些内容的值。您的问题中显示的Invoke方法将允许您的代码从ComboBox获取值,但在调试时不适用。
来自Debug Multithreaded Applications in Visual Studio
调试具有用户界面的多线程应用程序可能特别困难。在这种情况下,您可以考虑在另一台计算机上运行该应用程序并使用远程调试。有关信息,请参阅Remote Debugging in Visual Studio。