Unresponsive program

IneedaSmoke

Active member
Joined
Mar 4, 2008
Messages
26
Programming Experience
Beginner
Hey all. Trying to figure out how to make applications more responsive. I haven't been able to figure out how to make my applications stop having the "Not Responding" business.

I've tried delegates and thread sleeping to no avail :( I don't know if I'm just placing them wrong or what, so anywho here is a little test application for anyone who would like to make suggestions:

VB.NET:
Imports System.Threading


Public Class Form1



    Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
        Dim myProcCounter As New delProcCounter(AddressOf procCounter)
        myProcCounter.Invoke()

    End Sub

    Private Sub procCounter()
        Dim alStartingNumbers As New ArrayList

        alStartingNumbers = generateALList()

        For Each item In alStartingNumbers

            Dim myDoThis As New classDoThis
            myDoThis.startingNumber = item

            Dim myThread = New Thread(AddressOf myDoThis.procCounter)


            AddHandler myDoThis.updateInfo, AddressOf msgEventHandler

            myThread.Start()

            'Thread.CurrentThread.Sleep(10)


        Next


    End Sub

    Public Delegate Sub delProcCounter()


    Public Sub msgEventHandler(ByVal msg As String)



        If Me.InvokeRequired Then
           
            Dim delegate1 As New delUpdateTB(AddressOf msgEventHandler)
            Dim parameters(0) As String
            parameters(0) = msg.ToString
            Me.Invoke(delegate1, parameters)

        Else
            Dim myDel As delUpdateTB
            myDel = AddressOf updateTB

            myDel.Invoke(msg.ToString)

        End If





    End Sub


    Public Delegate Sub delUpdateTB(ByVal msg As String)


    Private Sub updateTB(ByVal msg As String)
        tbOutput.AppendText(msg)
        'MsgBox(msg)
    End Sub


    Private Function generateALList() As ArrayList
        Dim al As New ArrayList

        Dim i As Integer = 0
        For i = 0 To 500
            al.Add(i)
        Next

        Return al

    End Function


End Class


VB.NET:
Public Class classDoThis

    Public startingNumber As Double = 0


    Public Sub procCounter()

        Dim i As Integer = 0
        For i = 1 To 10
            startingNumber = startingNumber + i

            Try
                RaiseEvent updateInfo(startingNumber.ToString & vbCrLf)
            Catch ex As Exception
                MsgBox(ErrorToString)
            End Try



        Next

    End Sub

    Public Event updateInfo(ByVal myNumber As String)



End Class

TIA
 
A change to the code to this:

VB.NET:
 Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click

        'try with a delegate
        'Dim myProcCounter As New delProcCounter(AddressOf procCounter)
        'myProcCounter.Invoke()


        'try with a new thread
        Dim myProcThread = New Thread(AddressOf procCounter)
        myProcThread.Start()


    End Sub

    Private Sub procCounter()
        Dim alStartingNumbers As New ArrayList

        alStartingNumbers = generateALList()

        For Each item In alStartingNumbers

            Dim myDoThis As New classDoThis
            myDoThis.startingNumber = item

            Dim myThread = New Thread(AddressOf myDoThis.procCounter)


            AddHandler myDoThis.updateInfo, AddressOf msgEventHandler

            myThread.Start()

            Thread.CurrentThread.Sleep(25)


        Next


    End Sub

makes the above program responsive. Basically, I put the whole thing in a separate thread from the click button event. Also, I added a sleep of 25 milliseconds.

I will not be using this though. I noticed when I changed the class loop to an outrageous number, that the display functionality severely affects performance.

With the msgEventHandler, I max out one processor. Without it, I run between 80% and 60% on 8 cores.
 
Delegate.Invoke has no threading purpose, it is equivalent to calling the method directly, and it mostly used to call user defined method implementations (method pointers), for example provided as method parameters.

Delegate.BeginInvoke will call the method on a ThreadPool thread, and allows for a callback method (also called from ThreadPool) that is called when method is done, but requires Delegate.EndInvoke which is more work.

You can also use ThreadPool directly with QueueUserWorkItem method, it is easy, fast and cheap on resources, but will only allow a single Object parameter, so if you need to pass multiple things you have to bundle them to one object.

Creating Thread instances yourself is better for fewer, longer running tasks.

Control.Invoke/BeginInvoke calls the method on the controls thread (UI thread), for the purpose of accessing controls from different threads, where only difference is Invoke is blocking and BeginInvoke is non-blocking, this also don't require a Control.EndInvoke.
 
Back
Top