Изображение не отображается - программа зависает - PullRequest
0 голосов
/ 22 мая 2009

Программа запускается. Когда я нажимаю кнопку «Пуск», исходная форма исчезает, как я и предполагал, но затем просто висит там. Ни одна картинка не появляется. Процессор нагревается и становится громче. Он зависает, и мне иногда приходится нажимать CTRL + ALT + DEL, чтобы выйти из программы.


'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

Ответы [ 2 ]

1 голос
/ 22 мая 2009

Не пройдя весь код, я думаю, что следующий фрагмент является основной проблемой:

Do While (Flag = 0)
Loop

Я заметил, что вы устанавливаете флаг в ответ на некоторые события KeyPress, чтобы это работало, вам придется изменить цикл, по крайней мере, на

Do While (Flag = 0)
  Application.DoEvents
Loop

Но я бы настоятельно рекомендовал изменить дизайн, не требующий такой занятой петли

0 голосов
/ 03 октября 2009

У вас есть пара циклов «Do» («До» («Num = 10» »,« Do Пока »(« флаг = 0 »)»), которые никогда не остановятся, поэтому, когда программа нажмет на них, она войдет в бесконечный «бесконечный цикл». ».

Вы писали:

   Do While (Flag = 0)
   Loop

... но вам нужен некоторый код между этими двумя строками, который изменит значение Flag на что-то отличное от 0, иначе компьютер не сможет когда-либо выполнить это условие, и он будет безрезультатно зацикливаться вечно. например Этот гипотетический пример будет ждать, пока пользователь нажмет клавишу Escape:

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

Процессор нагревается, и охлаждающий вентилятор работает на полную мощность, потому что программа лихорадочно зацикливается, используя 100% процессорного времени.

(Я полагаю, вы ожидаете, что код обработки событий в вашей программе будет выполняться «в фоновом режиме» во время выполнения цикла, но на самом деле компьютер делает только одну вещь за раз, и поэтому он никогда не выходит из цикла для быть в состоянии запустить ваш обработчик событий. Если бы программа была «многопоточной», то это было бы возможно, но, как она написана, она «однопоточная», поэтому программа просто делает одну вещь за раз, последовательно, поэтому это никогда не выходит из цикла)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...