[英]Multi-Threading Glitch
I have a program that uses a label called Valve
and a textbox called Variable
我有一个程序使用名为
Valve
的标签和名为Variable
的文本框
The gist is that if the Variable = 0
then the label colour is gray, If the Variable = 1
then the label uses a thread which flashes between gray and red. 要点是,如果
Variable = 0
则标签颜色为灰色;如果Variable = 1
则标签使用的线程在灰色和红色之间闪烁。
This works almost perfectly apart from if changing between the two values very quickly (entering 0 then deleting it then entering 1, and so on) Then the thread speed increases (as if it is multi-threading). 这与在两个值之间快速更改(输入0然后将其删除然后输入1,依此类推)之间的变化非常完美,然后线程速度增加了(就像多线程一样)。
The strange thing is that if swapping between the values 0 & 1 slowly (every 2 seconds +), then it doesn't increase the blinking speed (this is what the program needs to do) 奇怪的是,如果缓慢地在值0和1之间交换(每2秒+),那么它不会增加闪烁速度(这是程序需要做的)
This is expanded code from the following question: vb.net multi threading 这是来自以下问题的扩展代码: vb.net多线程
Note: This is just a VB.NET conversion from my project on VisiWin.NET. 注意:这只是我在VisiWin.NET上的项目的VB.NET转换。 In this example the TextBox
Variable
will be an actual variable read from a PLC and the label Valve
will be triangles representing a process solenoid from a process flowsheet mimic. 在此示例中,TextBox
Variable
将是从PLC读取的实际变量,而Valve
标记将是代表过程流程图模拟中的过程螺线管的三角形。 Every solenoid will be controlled by different variables. 每个螺线管将由不同的变量控制。
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading
Imports System.Diagnostics
Public Class Form1
Private _flash As Boolean = False
Private Sub Variable1_TextChanged(sender As System.Object, e As System.EventArgs) Handles Variable.TextChanged
If Variable.Text = "1" And Not _flash Then
_flash = True
Dim FlashThread As New Thread(New ThreadStart(AddressOf FlashLabel))
FlashThread.Start()
End If
If Variable.Text = "0" Then
_flash = False
Valve.ForeColor = Color.Gray
End If
End Sub
Private Sub FlashLabel()
Dim _Color As Color = Color.Gray
While _flash
If Valve.ForeColor = _Color Then
Valve.ForeColor = Color.Red
Else
Valve.ForeColor = Color.Gray
End If
System.Threading.Thread.Sleep(2000)
End While
End Sub
End Class
What's happening here is that your first flashing thread is still running, it's just in the two second sleep phase. 这里发生的是您的第一个刷新线程仍在运行,仅在第二个睡眠阶段。 Your value changes to 0, it doesn't break out of the loop because it's asleep and then the variable changes back to 1 again, the thread wakes up and carries on, by which time you have spawned another thread doing the exact same thing, so it appears as if the thread is going faster.
您的值更改为0,因为它处于睡眠状态,所以不会中断循环,然后变量又变回1,该线程唤醒并继续运行,到那时您已经生成了另一个完全相同的线程,因此看起来好像线程运行得更快。
I would suggest changing this to a timer instead, as you can stop the timer when the variable is 0, and then restart it when it is 1: 我建议将其改为计时器,因为您可以在变量为0时停止计时器,然后在变量为1时重新启动计时器:
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading
Imports System.Diagnostics
Public Class Form1
Private _timer As New System.Windows.Forms.Timer()
Private Sub Variable1_TextChanged(sender As System.Object, e As System.EventArgs) Handles Variable.TextChanged
If Variable.Text = "1" And Not _flash Then
_flash = True
_timer.Interval = 2000
_timer.Enabled = True
_timer.Start()
End If
If Variable.Text = "0" Then
_flash = False
_timer.Stop()
_timer.Enabled = False
Valve.ForeColor = Color.Gray
End If
End Sub
Private Sub FlashLabel() Handles _timer.Tick
Dim _Color As Color = Color.Gray
If Valve.ForeColor = _Color Then
Valve.ForeColor = Color.Red
Else
Valve.ForeColor = Color.Gray
End If
End Sub
End Class
Docs for Timer: http://msdn.microsoft.com/en-gb/library/system.windows.forms.timer.aspx 计时器文档: http : //msdn.microsoft.com/en-gb/library/system.windows.forms.timer.aspx
Alternatively, you could store the thread in a field and terminate it when your variable is set to 0: 另外,您可以将线程存储在字段中,并在变量设置为0时终止该线程:
Imports Microsoft.VisualBasic
Imports System
Imports System.Collections
Imports System.Collections.Generic
Imports System.Drawing
Imports System.Windows.Forms
Imports System.Threading
Imports System.Diagnostics
Public Class Form1
Private _flash As Boolean = False
Private _flashThread as Thread
Private Sub Variable1_TextChanged(sender As System.Object, e As System.EventArgs) Handles Variable.TextChanged
If Variable.Text = "1" And Not _flash Then
_flash = True
_flashThread As New Thread(New ThreadStart(AddressOf FlashLabel))
_flashThread.Start()
End If
If Variable.Text = "0" Then
_flash = False
_flashThread.Abort()
Valve.ForeColor = Color.Gray
End If
End Sub
Private Sub FlashLabel()
Dim _Color As Color = Color.Gray
While _flash
If Valve.ForeColor = _Color Then
Valve.ForeColor = Color.Red
Else
Valve.ForeColor = Color.Gray
End If
System.Threading.Thread.Sleep(2000)
End While
End Sub
End Class
See http://msdn.microsoft.com/en-GB/library/ty8d3wta.aspx for notes on aborting threads, although I don't think any of this really applies to you, if it doesn't abort the thread during it's sleeping time, it should abort before the next iteration of the loop. 有关中止线程的说明,请参见http://msdn.microsoft.com/zh-CN/library/ty8d3wta.aspx ,尽管我认为这其中的任何一项对您都不适用,但前提是它在中止线程期间不会中止线程睡眠时间,它应该在循环的下一次迭代之前中止。
The problem is the following: 问题如下:
_flash
is False
: The thread is started, changes the color and sleeps 2 seconds _flash
为False
:线程启动,更改颜色并休眠2秒钟 _flash
is True
: _flash
will be set to False
. _flash
为True
: _flash
将设置为False
。 _flash
is False
again: A new thread is started. _flash
再次为False
:启动新线程。 Now, if steps 2 and 3 happen while the first thread sleeps, you have two running threads. 现在,如果第一个线程休眠时发生了步骤2和3,则您有两个正在运行的线程。 After the first thread is finished sleeping, it will see that
_flash
is True
and will continue running. 在第一个线程完成睡眠之后,它将看到
_flash
为True
并将继续运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.