0

我有一个程序,它使用一个名为的标签Valve和一个名为的文本框Variable

要点是,如果Variable = 0则标签颜色为灰色,如果Variable = 1则标签使用在灰色和红色之间闪烁的线程。

除了非常快速地在两个值之间更改(输入 0 然后删除它然后输入 1 等等)之外,这几乎可以完美地工作,然后线程速度会增加(就像它是多线程一样)。

奇怪的是,如果在值 0 和 1 之间缓慢交换(每 2 秒 +),那么它不会增加闪烁速度(这是程序需要做的)

这是来自以下问题的扩展代码:vb.net multi threading

注意:这只是我在 VisiWin.NET 上的项目的 VB.NET 转换。在此示例中,TextBoxVariable将是从 PLC 读取的实际变量,标签Valve将是三角形,表示来自过程流程图模拟的过程螺线管。每个螺线管将由不同的变量控制。

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
4

2 回答 2

3

这里发生的是您的第一个闪烁线程仍在运行,它只是处于第二个睡眠阶段。您的值更改为 0,它不会跳出循环,因为它处于睡眠状态,然后变量再次变回 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

计时器文档:http: //msdn.microsoft.com/en-gb/library/system.windows.forms.timer.aspx

或者,您可以将线程存储在一个字段中,并在您的变量设置为 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

有关中止线程的说明,请参阅http://msdn.microsoft.com/en-GB/library/ty8d3wta.aspx,尽管我认为这对您并不适用,如果它在执行期间没有中止线程睡眠时间,它应该在循环的下一次迭代之前中止。

于 2013-02-08T10:37:15.763 回答
0

问题如下:

  1. 你输入 1, _flashis False: 线程启动,改变颜色,休眠 2 秒
  2. 你输入 1 后快速输入 0,_flash就是True:_flash会被设置为False
  3. 你输入0后快速输入1,又_flashFalse:开始一个新线程。

现在,如果第 2 步和第 3 步在第一个线程休眠时发生,则您有两个正在运行的线程。在第一个线程完成睡眠后,它会看到它_flashTrue继续运行。

于 2013-02-08T10:33:26.937 回答