2013-02-08 133 views
0

我有一个使用标签的程序调用Valve和一个名为文本框Variable多线程毛刺

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

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

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

这是从以下问题展开代码:vb.net multi threading

注意:这只是我的项目在VisiWin.NET上的VB.NET转换。在这个例子中,文本框Variable将是从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 

回答

0

的问题如下:

  1. 输入1,_flashFalse:螺纹开始,改变了颜色,可供2秒
  2. 你进入1后迅速进入0, _flashTrue_flash将被设置为False
  3. 您在输入0后快速输入1,_flashFalse再次启动一个新线程。

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

+0

干杯,我有一种感觉是这个问题。有没有简单的解决方案?或者对于任何其他代码来说,变量切换太快以防止多线程问题? –

+0

@GarethAntonyFowell:我认为肖恩的答案指出要做什么来阻止它。我同意使用Timer而不是Thread。 –

+0

我以前使用过定时器,但是他们证明是有用的,但是我的项目将会太大,我将不得不使用数百个定时器,我想使用线程来创建我自己的属性绑定。正常的计时器不适合我的项目规模。 –

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 borting线程,尽管我不认为这对你真的适用,如果它在休眠期间不中止线程,它应该在下一次循环迭代之前中止。

+0

我以前使用过定时器,但是它们证明是有用的,但是我的项目会过大,我将不得不使用数百个定时器,我想使用线程来创建我自己的属性绑定。正常的计时器不适合我的项目规模。 –

+0

好吧,你知道你的项目比我好得多,但是定时器将所有这些线程包装成可能(并不总是)比你做的更好的方式。看起来你正在手动构建这些东西,也许你可以把它包装在一个辅助类或其他东西中并重新使用它?这只是一个建议=] – Sean

+0

助手类?我如何去做这些之一,因为我不相信我曾经使用过。 另外它将如何帮助闪烁的问题? –