none
Program freezes when mouse leaves the Form's Boundaries RRS feed

  • Question

  • Sometimes the freeze is temporary until the mouse returns, sometimes permanent, sometimes no freeze at all. Seems like moving the mouse up through the Title Bar freezes more often.

    Form Looks like this:


    TextBoxDisplay - upper Text Box
    BtnStopStart - Left Button, test = "Start"
    BtnCopy - Middle Button, text = "Copy"
    BtnTake - Right Button, text  = "Take"
    NUDHowmany - NumericUpDown, default is 8, min 8 max 32
    TextBoxResults - lower Text Box
    BGWGenerate - Background Worker Supports Cancellation - True, ReportsProgress = True
    Form is 480x120

    Code:

    Option Strict On
    Imports System.ComponentModel
    
    Public Class Form1
        Private OnOff As Boolean = False
        Private Password As String = ""
        Private RNG As New Random
        Private HowMany As Integer
    
        Private Sub BtnStopStart_Click(sender As Object, e As EventArgs) Handles BtnStopStart.Click
            OnOff = Not OnOff
            If OnOff Then
                BtnStopStart.Text = "Stop"
                Password = ""
                BGWGenerate.RunWorkerAsync()
            Else
                BGWGenerate.CancelAsync()
                BtnStopStart.Text = "Start"
            End If
        End Sub
    
        Private Sub BGWGenerate_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGWGenerate.DoWork
            Do
                If BGWGenerate.CancellationPending Then Exit Sub
                If OnOff Then
                    Do
                        If BGWGenerate.CancellationPending Then Exit Sub
                    Loop Until Password = ""
                    For Index As Integer = 1 To 64
                        If BGWGenerate.CancellationPending Then Exit Sub
                        Password &= Chr(RNG.Next(32, 127))
                    Next
                    BGWGenerate.ReportProgress(1)
                End If
            Loop
        End Sub
    
        Private Sub BGWGenerate_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BGWGenerate.ProgressChanged
            TextBoxDisplay.Text = Password
            Password = ""
        End Sub
    
        Private Sub Form1_FormClosing(sender As Object, e As FormClosingEventArgs) Handles Me.FormClosing
            OnOff = False
            BGWGenerate.CancelAsync()
        End Sub
    
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
            HowMany = CInt(NUDHowmany.Value)
            OnOff = False
        End Sub
    
        Private Sub BtnCopy_Click(sender As System.Object, e As System.EventArgs) Handles BtnCopy.Click
            TextBoxResults.Text = TextBoxDisplay.Text
        End Sub
    
        Private Sub NUDHowmany_ValueChanged(sender As System.Object, e As System.EventArgs) Handles NUDHowmany.ValueChanged
            HowMany = CInt(NUDHowmany.Value)
        End Sub
    
        Private Sub BtnTake_Click(sender As System.Object, e As System.EventArgs) Handles BtnTake.Click
            TextBoxResults.Text = TextBoxDisplay.Text.Substring(RNG.Next(0, TextBoxDisplay.TextLength - HowMany), HowMany)
        End Sub
    End Class

    I have never seen anything like this happen.


    • Edited by Devon_Nullman Sunday, October 1, 2017 8:50 PM Forgot the Background Worker
    Sunday, October 1, 2017 8:36 PM

All replies

  • A Do loop (inside a Do loop)?

    It doesn't matter that it's on another thread - your computer is perpetually tied up trying to process that.

    Refactor that and see if that's not a better solution.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, October 1, 2017 9:09 PM
  • Hi

    Tried your code, and apart from being unable to see what you intend it to do, I can't reproduce the effect you are seeing.


    Regards Les, Livingston, Scotland

    Sunday, October 1, 2017 9:30 PM
  • A Do loop (inside a Do loop)?

    It doesn't matter that it's on another thread - your computer is perpetually tied up trying to process that.

    Refactor that and see if that's not a better solution.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    I will work on that but still - why would "leaving" the form cause freezing. Nothing else does, as long as the mouse in inside the form.

    Edit - I changed the Background Worker as follows:

        Private Sub BGWGenerate_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGWGenerate.DoWork
            Do
                Password = ""
                For Index As Integer = 1 To 64
                    If BGWGenerate.CancellationPending Then Exit Sub
                    Password &= Chr(RNG.Next(32, 127))
                Next
                Threading.Thread.Sleep(1)
                BGWGenerate.ReportProgress(1)
                Threading.Thread.Sleep(2)
            Loop
        End Sub
    
    This stops the freezing when the mouse leaves the form but if I click on the TitleBar it freezes for a split second which seems odd.

    • Edited by Devon_Nullman Sunday, October 1, 2017 9:51 PM More Info
    Sunday, October 1, 2017 9:33 PM

  • I will work on that but still - why would "leaving" the form cause freezing. Nothing else does, as long as the mouse in inside the form.

    Let's test it and see:

    Before each loop, add a Threading.Thread.Sleep(x) and see if it makes any difference?

    If not then maybe I'm wrong but it sure seems that might be a problem.

    ***** EDIT *****

    ...where x >0


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Sunday, October 1, 2017 9:38 PM ...added note about infinite wait
    Sunday, October 1, 2017 9:36 PM

  • I will work on that but still - why would "leaving" the form cause freezing. Nothing else does, as long as the mouse in inside the form.

    Let's test it and see:

    Before each loop, add a Threading.Thread.Sleep(x) and see if it makes any difference?

    If not then maybe I'm wrong but it sure seems that might be a problem.

    ***** EDIT *****

    ...where x >0


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    I added that edit to my post after you replied

    Sunday, October 1, 2017 10:16 PM

  • I will work on that but still - why would "leaving" the form cause freezing. Nothing else does, as long as the mouse in inside the form.

    Let's test it and see:

    Before each loop, add a Threading.Thread.Sleep(x) and see if it makes any difference?

    If not then maybe I'm wrong but it sure seems that might be a problem.

    ***** EDIT *****

    ...where x >0


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    I added that edit to my post after you replied

    I think that if you'll refactor it, you'll see an improvement.

    if "password" is a string, consider changing that to a StringBuilder and use the .Append method.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, October 1, 2017 10:23 PM

  • I will work on that but still - why would "leaving" the form cause freezing. Nothing else does, as long as the mouse in inside the form.

    Let's test it and see:

    Before each loop, add a Threading.Thread.Sleep(x) and see if it makes any difference?

    If not then maybe I'm wrong but it sure seems that might be a problem.

    ***** EDIT *****

    ...where x >0


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    I added that edit to my post after you replied

    I think that if you'll refactor it, you'll see an improvement.

    if "password" is a string, consider changing that to a StringBuilder and use the .Append method.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    New DoWork sub

        Private Sub BGWGenerate_DoWork(sender As Object, e As System.ComponentModel.DoWorkEventArgs) Handles BGWGenerate.DoWork
            Do
                If BGWGenerate.CancellationPending Then Exit Sub
                Password.Clear()
                Threading.Thread.Sleep(2)
                For Index As Integer = 1 To 64
                    Password.Append(Chr(RNG.Next(32, 127)))
                Next
                Threading.Thread.Sleep(2)
                BGWGenerate.ReportProgress(1)
                Threading.Thread.Sleep(2)
            Loop
        End Sub

    Still stops when TitleBar clicked - maybe it is because that's how a "Move Form" starts ?

    Monday, October 2, 2017 12:44 AM
  • Still stops when TitleBar clicked - maybe it is because that's how a "Move Form" starts ?

    It may be that you're throwing too much out to the UI thread (or too quickly).

    Consider something like this and see if it helps:

    Option Strict On
    Option Explicit On
    Option Infer Off
    
    Public Class Form1
        Private WithEvents bgw As System.ComponentModel.BackgroundWorker
    
        Private Sub _
            Form1_Load(sender As System.Object, _
                       e As System.EventArgs) _
                       Handles MyBase.Load
    
            bgw = New System.ComponentModel.BackgroundWorker _
                With {.WorkerSupportsCancellation = True}
    
            bgw.RunWorkerAsync()
    
        End Sub
    
    
    
        Private Sub _
            bgw_DoWork(sender As Object, _
                       e As System.ComponentModel.DoWorkEventArgs) _
                       Handles bgw.DoWork
    
            Dim rand As New Random
            Dim result As New List(Of String)
            Dim sb As New System.Text.StringBuilder(64)
    
            Do Until result.Count = 1000000
                If bgw.CancellationPending Then
                    e.Cancel = True
                Else
                    For Index As Integer = 1 To 64
                        sb.Append(Chr(rand.Next(32, 127)))
                    Next
    
                    ' Note that the following should be
                    ' used if you don't care if there
                    ' are duplicates in the list:
    
                    ' =====================
                    result.Add(sb.ToString)
                    ' =====================
    
                    ' If you want to check for
                    ' duplicates, comment out what's
                    ' above and uncomment this one but
                    ' do realize that this is an O(n)
                    ' operation so it will slow things
                    ' down quite a lot:
    
                    ' =====================
                    'If Not result.Contains(sb.ToString) Then
                    '    result.Add(sb.ToString)
                    'End If
                    ' =====================
    
                    sb.Clear()
                End If
            Loop
    
            e.Result = result.ToArray
    
        End Sub
    
    
    
        Private Sub _
            bgw_RunWorkerCompleted(sender As Object, _
                                   e As System.ComponentModel.RunWorkerCompletedEventArgs) _
                                   Handles bgw.RunWorkerCompleted
    
            If e.Error IsNot Nothing Then
                MessageBox.Show(String.Format("An error occurred:{0}{0}{1}", _
                                              vbCrLf, e.Error.Message), _
                                              "Exception Thrown")
    
            ElseIf e.Cancelled Then
                MessageBox.Show("The worker was cancelled.")
    
            Else
                If e.Result IsNot Nothing Then
                    Dim passwords As IEnumerable(Of String) = _
                        DirectCast(e.Result, IEnumerable(Of String))
    
                    Stop
                End If
            End If
    
        End Sub
    End Class


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Monday, October 2, 2017 11:50 AM