- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
VB.NET 2010、.NET 4
你好,
我一直在使用一个非常漂亮的通用调用方法来从后台线程更新 UI。我忘记了从哪里复制它(从 C# 将其转换为 VB.NET),但它是:
Public Sub InvokeControl(Of T As Control)(ByVal Control As t, ByVal Action As Action(Of t))
If Control.InvokeRequired Then
Try
Control.Invoke(New Action(Of T, Action(Of T))(AddressOf InvokeControl), New Object() {Control, Action})
Catch ex As Exception
End Try
Else
Action(Control)
End If
End Sub
Public Function InvokeControl(Of T As Control)(ByVal Control As t, ByVal Action As Action(Of t)) As IAsyncResult
If Control.InvokeRequired Then
Try
Return Control.BeginInvoke(New Action(Of T, Action(Of T))(AddressOf InvokeControl), New Object() {Control, Action})
Catch ex As Exception
Return Nothing
End Try
Else
Action(Control)
Return Nothing
End If
End Function
InvokeControl(SomeTextBox, Sub(x) x.Text = "Some text")
SomeTextBox {Text = (Text) threw an exception of type Microsoft.VisualStudio.Debugger.Runtime.CrossThreadMessagingException.}
Private Sub MasterTimer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles MasterTimer.Elapsed
MasterTimer.Enabled = False
If Not MasterTimer.Interval = My.Settings.TimingMasterTimerInterval Then
MasterTimer.Interval = My.Settings.TimingMasterTimerInterval
NewEventLogEntry("The master timer's interval has been changed to " & MasterTimer.Interval.ToString & " milliseconds.")
End If
InvokeControl(TimerPictureBox, Sub(x) x.Toggle(True))
ReadFromDevices()
UpdateIndicators()
'This block is not executing when the error is thrown
If Mode > RunMode.NotRunning Then
UpdateProcessTime()
UpdateRemainingTime()
UpdateStatusTime()
End If
'This block is not executing when the error is thrown
If Mode = RunMode.Running Then
CheckMillerCurrent()
CheckTolerances()
End If
MasterTimer.Enabled = True
End Sub
Private Sub ReadFromDevices()
For Each dev As Device In Devices
Try
If dev.GetType.Equals(GetType(Miller)) Then
Dim devAsMiller As Miller = CType(dev, Miller)
With devAsMiller
If .PowerOn.Enabled Then .PowerOn.Read()
If .CurrentRead.Enabled Then .CurrentRead.Read()
If .VoltageRead.Enabled Then .VoltageRead.Read()
If .Trigger.Enabled Then .Trigger.Read()
If .Shutter.Enabled Then .Shutter.Read()
End With
ElseIf dev.GetType.Equals(GetType(SubstrateBiasVoltage)) Then
Dim devAsSubstrateBiasVoltage As SubstrateBiasVoltage = CType(dev, SubstrateBiasVoltage)
With devAsSubstrateBiasVoltage
If .LambdaCurrentRead.Enabled Then .LambdaCurrentRead.Read()
If .LambdaVoltageRead.Enabled Then .LambdaVoltageRead.Read()
If .BiasResistor.Enabled Then .BiasResistor.Read()
If .Pinnacle.Enabled Then .Pinnacle.Read()
End With
Else
If dev.Enabled Then dev.Read()
End If
Catch ex As Exception
NewEventLogEntry("An error occurred while trying to read from a device.", ex, EventLogItem.Types.Warning)
End Try
Next
End Sub
Private Sub UpdateIndicators()
Dim ObjLock As New Object
SyncLock ObjLock
With Devices
InvokeControl(EmergencyStopPictureBox, Sub(x As DigitalPictureBox) x.Toggle(Mode > RunMode.NotRunning))
InvokeControl(MillerCurrentIndicator, Sub(x) x.Text = .Miller1.CurrentRead.GetParsedValue.ToString)
InvokeControl(MillerVoltageIndicator, Sub(x) x.Text = .Miller1.VoltageRead.GetParsedValue.ToString)
With .SubstrateBiasVoltage
InvokeControl(LambdaVoltageIndicator, Sub(x) x.Text = .LambdaVoltageRead.GetParsedValue.ToString)
InvokeControl(LambdaCurrentIndicator, Sub(x) x.Text = .LambdaCurrentRead.GetParsedValue.ToString)
InvokeControl(PinnacleVoltageIndicator, Sub(x) x.Text = .Pinnacle.GetParsedValue.ToString)
InvokeControl(PinnacleCurrentIndicator, Sub(x) x.Text = .Pinnacle.ReadCurrent.ToString)
End With
InvokeControl(HeaterPowerIndicator, Sub(x) x.Text = .HeaterPower.GetParsedValue.ToString)
InvokeControl(ConvectronIndicator, Sub(x) x.Text = .Convectron.GetParsedValue.ToString)
If .Baratron.GetParsedValue > 200 Then
InvokeControl(BaratronIndicator, Sub(x) x.Text = "OFF")
Else
InvokeControl(BaratronIndicator, Sub(x) x.Text = .Baratron.GetParsedValue.ToString)
End If
If .Ion.GetParsedValue > 0.01 Then
InvokeControl(IonIndicator, Sub(x) x.Text = "OFF")
Else
InvokeControl(IonIndicator, Sub(x) x.Text = .Ion.GetParsedValue.ToString)
End If
InvokeControl(ArgonFlowRateIndicator, Sub(x) x.Text = .ArgonFlowRate.GetParsedValue.ToString)
InvokeControl(NitrogenFlowRateIndicator, Sub(x) x.Text = .NitrogenFlowRate.GetParsedValue.ToString)
InvokeControl(GateValvePositionIndicator, Sub(x) x.Text = .GateValvePosition.GetParsedValue.ToString)
InvokeControl(RoughingPumpPowerOnIndicator, Sub(x As PowerButton) x.IsOn = .RoughingPumpPowerOn.Value = Power.On)
ToggleImageList(.Miller1.CurrentRead.ImageList, .Miller1.CurrentRead.GetParsedValue > My.Settings.MinimumMillerCurrent)
ToggleImageList(.Miller1.Trigger.ImageList, .Miller1.Trigger.GetParsedValue = Power.On)
ToggleImageList(.HeaterPower.ImageList, .HeaterPower.Value > 0)
With .SubstrateBiasVoltage
ToggleImageList(.LambdaVoltageRead.ImageList, .LambdaVoltageRead.GetParsedValue > 0 And .BiasResistor.GetParsedValue = BiasResistor.Lambda)
ToggleImageList(.Pinnacle.ImageList, .Pinnacle.GetParsedValue > 10 And .BiasResistor.GetParsedValue = BiasResistor.Pinnacle)
End With
ToggleImageList(.ArgonValveOpen.ImageList, .ArgonValveOpen.Value = Valve.Open)
ToggleImageList(.NitrogenValveOpen.ImageList, .NitrogenValveOpen.Value = Valve.Open)
ToggleImageList(.RoughingPumpValveOpen.ImageList, .RoughingPumpValveOpen.Value = Valve.Open)
ToggleImageList(.SlowPumpDownValve.ImageList, .SlowPumpDownValve.Value = Valve.Open)
ToggleImageList(.RotationPowerOn.ImageList, .RotationPowerOn.Value = Power.On)
ToggleImageList(.WaterMonitor1.ImageList, .WaterMonitor1.Value = Power.On And .WaterMonitor2.Value = Power.On)
ToggleImageList(.GateValvePosition.ImageList, .GateValvePosition.SetValue > 0)
End With
End SyncLock
End Sub
Private Sub ToggleImageList(ByRef ImageList As ImageList, ByVal IsOn As Boolean)
For Each img As OnOffPictureBox In ImageList
SafeInvokeControl(img, Sub(x As OnOffPictureBox) x.Toggle(IsOn))
Next
End Sub
最佳答案
很难使用调试来捕获异常,因为它会发生在多个 PostMessage
中的任何一个上。对 UI 消息泵的调用(由 InvokeControl
和 BeginInvoke
调用引起)。 Visual Studio 将很难打破异常。这可能就是为什么看起来异常“神奇地”被抛出的原因。
您的问题不在于您对 InvokeControl
的实现。但在 UpdateIndicators
方法。这是因为使用了With
语句和异步 UI 线程调用如下:
With Devices
...
InvokeControl(MillerCurrentIndicator, Sub(x) x.Text = .Miller1.CurrentRead.GetParsedValue.ToString)
...
End With
Sub(x)
代码正在通过在 UI 线程上发布消息在 UI 线程上执行,当前线程上的调用代码极有可能在 UI 线程执行之前已经完成。
With
陈述。实质上,编译器为
With
创建了一个匿名局部变量。设置为
Nothing
的语句在
End With
陈述。
Dim p As New Person
With p
.Name = "James"
.Age = 40
End With
Dim p As New Person
Dim VB$t_ref$L0 As Person = p
VB$t_ref$L0.Name = "James"
VB$t_ref$L0.Age = 40
VB$t_ref$L0 = Nothing
Nothing
并且您得到“对象引用未设置为对象的实例”异常。
Dim VB$t_ref$L0 = Devices
Dim action = new Action(Sub(x) x.Text = VB$t_ref$L0.Miller1.CurrentRead.GetParsedValue.ToString);
VB$t_ref$L0 = Nothing
action(MillerCurrentIndicator);
VB$t_ref$L0
时变量已设置为
Nothing
哇!
With
陈述。他们很坏。
SyncLock
代码使用了一个局部锁定变量,这实际上使锁定变得无用。所以不要这样做:
Private Sub UpdateIndicators()
Dim ObjLock As New Object
SyncLock ObjLock
With Devices
...
End With
End SyncLock
End Sub
Private ObjLock As New Object
Private Sub UpdateIndicators()
SyncLock ObjLock
With Devices
...
End With
End SyncLock
End Sub
InvokeControl
的调用在
UpdateIndicators
方法使调试代码变得困难。将所有这些调用减少到一个调用应该会极大地帮助您。试试这个:
Private Sub UpdateIndicators()
SyncLock ObjLock
InvokeControl(Me, AddressOf UpdateIndicators)
End SyncLock
End Sub
Private Sub UpdateIndicators(ByVal form As ControlInvokeForm)
With Devices
EmergencyStopPictureBox.Toggle(Mode > RunMode.NotRunning)
MillerCurrentIndicator.Text = .Miller1.CurrentRead.GetParsedValue.ToString
...
ToggleImageList(.GateValvePosition.ImageList, .GateValvePosition.SetValue > 0)
End With
End Sub
With Devices
使这些工作的代码。
If .Ion.GetParsedValue > 0.01 Then
InvokeControl(IonIndicator, Sub(x) x.Text = "OFF")
Else
InvokeControl(IonIndicator, Sub(x) x.Text = .Ion.GetParsedValue.ToString)
End If
.Ion.GetParsedValue
的值在被评估的条件和
Else
之间可能发生了变化。正在执行的语句。这很复杂,因为
If
上的条件语句在当前线程上计算,但
Else
语句在 UI 线程上执行,因此延迟可能很大。此外,如果
.Ion.
类不是线程安全的,您将自己暴露在潜在的错误中。
Dim parsedIonValue = .Ion.GetParsedValue
If parsedIonValue > 0.01 Then
InvokeControl(IonIndicator, Sub(x) x.Text = "OFF")
Else
InvokeControl(IonIndicator, Sub(x) x.Text = parsedIonValue.ToString)
End If
With
问题。)
AutoReset = True
在您的
MasterTimer
上自动调用
Enabled = False
当事件触发以避免竞争条件的(远程)可能性时。
With Devices
在
UpdateIndicators
方法,但你有一个
For Each
在
ReadFromDevices
中循环方法。
Devices
then 似乎是一个集合,但
UpdateIndicators
中的代码正在使用
Devices
对象好像是
Device
目的。它正在调用
.SubstrateBiasVoltage
在
Devices
目的。所以我不确定对象
Devices
到底是什么实际上是在做。
ToggleImageList
您传递的方法
ImageList
正在传递参数
ByRef
但您没有更改对
ImageList
的引用.最好在
ByVal
中传递以避免潜在的错误。
If dev.GetType.Equals(GetType(Miller)) Then
Dim devAsMiller As Miller = CType(dev, Miller)
With devAsMiller
Dim devAsMiller = TryCast(dev, Miller)
If devAsMiller IsNot Nothing Then
With devAsMiller
关于VB.NET 尝试将泛型 Invoke 方法修改为泛型 BeginInvoke 方法,出现意外问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3886187/
前言: 有时候,一个数据库有多个帐号,包括数据库管理员,开发人员,运维支撑人员等,可能有很多帐号都有比较大的权限,例如DDL操作权限(创建,修改,删除存储过程,创建,修改,删除表等),账户多了,管理
这个问题已经有答案了: Condition variable deadlock (2 个回答) 已关闭 5 年前。 在研究多线程时,我编写了以下代码,但在屏幕上没有观察到输出。我在这里做错了什么?我期
复制代码 代码如下: <IfModule mod_rewrite.c> RewriteEngineOn RewriteBase/ #将www.zzvips.com跳转到www.zzv
复制代码 代码如下: <IfModule mod_rewrite.c> RewriteEngine On RewriteBase / # 把 www.zzvips.com
复制代码 代码如下: Const T_GATEWAY = "1.1.1.1" '网关 Const T_NEWDNS1 = "2.2.2.2" 'DNS1
0. 修改索引 大文本字段支持排序 PUT http://localhost:9200/lrc_blog/_mapping //请求体 { "properties": { "title": { "t
仅 react 当状态发生变化时重新渲染 . 那么为什么我会直接看到我对真实 DOM 所做的更改呢? 我知道我正在修改真实的 DOM,但是当我根本没有改变状态时触发重新渲染的是什么。 import R
Xcode beta 5 推出 @FetchRequest对于 SwiftUI。 我有一个 View ,它有一个 @FetchRequest . NSFetchRequest是在管理器中创建的,该管理
关闭。这个问题需要更多 focused .它目前不接受答案。 想改进这个问题?更新问题,使其仅关注一个问题 editing this post . 7年前关闭。 Improve this questi
我有一个表达式[text][id]应替换为链接 text 解决方案是( id 是整数) $s = preg_replace("/\[([^\]]+)(\]*)\]\[([0-9]+)\]/","$1$
我在 repo 中有一个文件,我不想让任何人更新。 我能做什么? 最佳答案 你想要svn锁:http://www.linxit.de/svnbook/en/1.2/svn.ref.svn.c.lock
说我有项目 list 。我想导出到csv,但在此之前我想做一些计算/修改。 基本上,设置如下所示: PS C:\Files> gci Directory: C:\Files Mode
我有一个非常简单的问题 - 是否可以修改 Java API 的源代码,例如Junit,JABX ? 我知道这似乎是一个非常愚蠢的问题,但它一直困扰着我一段时间。 最佳答案 如果您可以掌握源代码,那么请
我有一个带有变量/列的小标题,其中包括不同形状的小标题列表。我想为其中一个变量中的每个(子)标题添加一个变量/列。 例如此类数据 library("tibble") aaa aaa # A tibb
我有几个菜单,可以在单击时向当前链接添加变量。这是一个例子: 1 2 3 x y z 我的问题是,如果我选择“y”2次,它会添加“&cord=y”2次。相反,我希望它替
我有两个项目:一个服务项目和一个服务安装程序项目。服务项目具有适合我的产品的装配信息。它包括公司信息和正确的服务名称。一旦服务实际安装,所有这些似乎都会被忽略。安装服务时,它使用在服务安装程序的ini
以下代码何时可能产生副作用? @some = map { s/xxx/y/; $_ } @some; perlcritic 将其解释为危险的,因为例如: @other = map { s/xxx/y/
我想知道以下哪种解决方案更好:我想修改一些 .class 文件,我意识到有两种方法可以做到这一点: 反编译.class文件,修改它,最后再次编译。 - 直接用十六进制编辑器修改。 谢谢 最佳答案 在这
这是我的按钮代码 onclick 我希望我的程序等待用户单击一个 JPanel,并且当用户单击 JPanel 时,它应该在控制台上打印其名称。 此按钮代码未显示输出 JPopupMenu popu
我正在使用一个具有“getName()”方法的特定 API。 getName() 返回一个字符串。是否可以修改该字符串? API 中不包含修饰符方法,并且 String getName() 返回的是私
我是一名优秀的程序员,十分优秀!