2009-05-21 20 views
0

Das Programm wird gestartet. Wenn ich auf die Schaltfläche Start klicke, verschwindet das ursprüngliche Formular genau so, wie ich es beabsichtigt habe, aber dann hängt es einfach dort. Kein Bild erscheint. Die CPU heizt auf und wird lauter. Es friert ein und ich muss manchmal STRG + ALT + ENTF einfach nur um das Programm zu beenden.Bild wird nicht angezeigt - Programm wird eingefroren


'Reaction.exe 

'Picture comes up once, user presses left side of keyboard (Q,A,or Z) 
'Picture comes up a second time, user presses right side of keyboard (P,L,or M) 
'A total of 10 .bmps, pictures show up randomly, a picture will only show up twice 
'Time (in millisecods) is recorded for each attempt 
'If user presses correct key, 
'For example if user presses 2 and it is the 2nd time the picture has shown up 
'Accuracy goes up a point (maximum of 10) 
'If user presses wrong key, 
'For example if user presses 2 even though the picture has only shown up once 
'Accuracy goes down a point (minimum of 0) 


Public Class Form_Main 


'Declare Globals' 
Public X As Integer = 0 'Used in DisplayImage() function 
Public I As Integer = 0 'Used for Times array and CalcTime() function 
Public Num As Integer = 0 'Used in branches 
Public Flag As Integer = 0 
Public Accuracy As Integer = 0 
Public Speed As Double = 0 
Public Delay As Integer = 0 
Public Timer_Start As Double = 0 
Public Timer_End As Double = 0 

'Arrays 
'Times Array 
Public Times(20) As Double 'Holds 20 times (since each picture will pop up twice)' 

'Main Array 
'Field = How many images will be used (Default is 10, for 10 pictures) 
'Value: 
'0 = Picture hasn't been used yet 
'1 = Picutre has been used 
'2 = Picture has already been used twice, and will not appear again 
Dim MainArray(10) As Integer 


' Start Button click (Main Function) 
Private Sub Button_Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Start.Click 
    ' Disable and hide the form 
    RadioButton_Images.Visible = False 
    RadioButton_Inkblots.Visible = False 
    RadioButton_Words.Visible = False 
    Button_Start.Visible = False 
    Button_Reset.Visible = False 
    RadioButton_Images.Enabled = False 
    RadioButton_Inkblots.Enabled = False 
    RadioButton_Words.Enabled = False 
    Button_Start.Enabled = False 
    Button_Reset.Enabled = False 

    'Images branch 
    If RadioButton_Images.Checked Then 
     Images() 
    End If 

    'Show the Reset Button 
    Button_Reset.Visible = True 
    Button_Reset.Enabled = True 
End Sub 


'Functions 
'Images() Function 
Private Function Images() As Action 
    Do Until (Num = 10) 
     Timer_Start = 0 
     Timer_End = 0 
     Flag = 0 
     Delay = Rand(3000, 6000) 
     System.Threading.Thread.Sleep(Delay) '3-6 second delay 
     DisplayImage() 
     Timer_Start = TimeOfDay.Millisecond 
     Do While (Flag = 0) 
     Loop 
     CalcTime() 
    Loop 
End Function 


'Rand() Function (returns a random integer between (x,y)) 
Private Function Rand(ByVal Low As Long, ByVal High As Long) As Long 
    'randomize function 
    Randomize() 
    Rand = Int((High - Low + 1) * Rnd()) + Low 
End Function 


'DisplayImage() Function 
Private Function DisplayImage() As Action 
    Do Until PictureBox.Visible = True 
     X = Rand(1, 10) 'Get a random number from 1 to 10 

     Select Case X 
      Case Is = 1 
       If MainArray(X) = 0 Then     'First time the picture is used 
        PictureBox.ImageLocation = "C:\Reaction\Images\1.bmp" 
        MainArray(X) = 1 
        PictureBox.Visible = True 
       ElseIf MainArray(X) = 1 Then    'Second time the picture is up 
        PictureBox.ImageLocation = "C:\Reaction\Images\1.bmp" 
        MainArray(X) = 2 
        Num = Num + 1 
        PictureBox.Visible = True 
       Else          'If MainArray(X) doesn't = 1 or 0 
       End If          'Then endif and get another rand # 
      Case Is = 2 
       If MainArray(X) = 0 Then 
        PictureBox.ImageLocation = "C:\Reaction\Images\2.bmp" 
        MainArray(X) = 1 
        PictureBox.Visible = True 
       ElseIf MainArray(X) = 1 Then 
        PictureBox.ImageLocation = "C:\Reaction\Images\2.bmp" 
        MainArray(X) = 2 
        Num = Num + 1 
        PictureBox.Visible = True 
       Else 
       End If 
      Case Is = 3 
       If MainArray(X) = 0 Then 
        PictureBox.ImageLocation = "C:\Reaction\Images\3.bmp" 
        MainArray(X) = 1 
        PictureBox.Visible = True 
       ElseIf MainArray(X) = 1 Then 
        PictureBox.ImageLocation = "C:\Reaction\Images\3.bmp" 
        MainArray(X) = 2 
        Num = Num + 1 
        PictureBox.Visible = True 
       Else 
       End If 
       ... 
     End Select 
    Loop 
End Function 


Private Function CalcTime() As Action 
    'Calculates the time in milliseconds 
    'Records to Times() array 
    Times(I) = Timer_Start - Timer_End 
    I = I + 1 
End Function 


Private Sub Form_Main_KeyPress(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyPressEventArgs) Handles MyBase.KeyPress 

    'Keypress Q, A, or Z if the picture is seen for the first time 
    'Otherwise one accuracy point is deducted 
    If e.KeyChar = "Q" Or "A" Or "Z" Or "q" Or "a" Or "z" Then 
     If PictureBox.Visible = True Then 
      If MainArray(X) = 1 Then 
       Timer_End = TimeOfDay.Millisecond 
       PictureBox.Image = Nothing 
       PictureBox.Visible = False 
       Accuracy = Accuracy + 1 
       Flag = 1 
      Else 
       Timer_End = TimeOfDay.Millisecond 
       PictureBox.Image = Nothing 
       PictureBox.Visible = False 
       Accuracy = Accuracy - 1 
       Flag = 1 
      End If 
     End If 
    End If 

    'Keypress for second occurance 
    If e.KeyChar = "P" Or "L" Or "M" Or "p" Or "l" Or "m" Then 
     If PictureBox.Visible = True Then 
      If MainArray(X) = 2 Then 
       Timer_End = TimeOfDay.Millisecond 
       PictureBox.Image = Nothing 
       PictureBox.Visible = False 
       Accuracy = Accuracy + 1 
       Flag = 1 
      Else 
       Timer_End = TimeOfDay.Millisecond 
       PictureBox.Image = Nothing 
       PictureBox.Visible = False 
       Accuracy = Accuracy - 1 
       Flag = 1 
      End If 
     End If 
    End If 
End Sub 



'Reset button 
Private Sub Button_Reset_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_Reset.Click 
    'Reset all global variables 
    X = 0 
    I = 0 
    Num = 0 
    Flag = 0 
    Accuracy = 0 
    Speed = 0 
    Delay = 0 
    Timer_Start = 0 
    Timer_End = 0 
    'temporarily use I and X to clear out MainArray() and Times() array 
    For I = 0 To I = 10 
     MainArray(I) = 0 
    Next 

    For X = 0 To X = 20 
     Times(X) = 0 
    Next 
    'Reset back to 0 
    X = 0 
    I = 0 

    'Enable and show the form, hiding the reset button 
    RadioButton_Images.Visible = True 
    RadioButton_Inkblots.Visible = True 
    RadioButton_Words.Visible = True 
    Button_Start.Visible = True 
    Button_Reset.Visible = False 
    RadioButton_Images.Enabled = True 
    RadioButton_Inkblots.Enabled = True 
    RadioButton_Words.Enabled = True 
    Button_Start.Enabled = True 
    Button_Reset.Enabled = False 
End Sub 

End Class 

Antwort

1

Ohne den gesamten Code durchlaufen, ich denke, das folgende Fragment ist das Hauptproblem:

Do While (Flag = 0) 
Loop 

Ich stelle fest, dass Sie die Flag in Reaktion auf einige KeyPress Ereignisse setzen weiter auf , um diese Arbeit zu machen, müssen Sie die Schleife zumindest ändern, um

Do While (Flag = 0) 
    Application.DoEvents 
Loop 

Aber ich würde stro ngly suggerieren ein Re-Design, das keine solche Busy-Schleife benötigt

0

Sie haben ein Paar Do While-Schleifen (Do Until (Num = 10), Do While (Flag = 0)), die niemals aufhören werden, Wenn das Programm sie trifft, wird es in eine endlose "Endlosschleife" gehen.

Sie schrieb:

 
    Do While (Flag = 0) 
    Loop 

... aber Sie müssen einen Code zwischen diesen beiden Linien, die den Wert der Flagge auf etwas anderes als 0 ändern, sonst gibt es keine Möglichkeit der Computer jemals erfüllen kann der Zustand, und es wird für immer für immer reibungslos Schleife. z.B. Diese hypothetische Beispiel wäre für den Benutzer warten, um die Escape-Taste drücken:

 
    Do While (Flag = 0) 
     If UserPressedEscape() Then Flag = 1 
    Loop 

Die CPU erwärmt sich und der Lüfter läuft mit voller Lautstärke, da das Programm hektisch wird Looping, 100% CPU-Zeit.

(Ich stelle mir vor, Sie erwarten, dass der Ereignisbehandlungscode in Ihrem Programm "im Hintergrund" ausgeführt wird, während Ihre Schleife läuft, aber in Wirklichkeit macht der Computer nur eine Sache zu einer Zeit, und so verlässt er die Schleife nie Wenn das Programm "multi-threaded" wäre, dann wäre das möglich, aber so, wie es geschrieben ist, ist es "single-threaded", so dass das Programm einfach eine Sache nach der anderen ausführt. so kommt es nie aus der Schleife)