multithreading - slower than single threading RRS feed

  • Question

  • When I using this code with timer all is good but I want use with multithread but when I use with multithread so slowy working.

    My Codes

    Imports System.Runtime.InteropServices
    Imports System.String
    Imports System.Net
    Imports System.IO
    Imports System.Threading
    Imports System.Media
    Public Class Form1
        Dim MyThreadExample As Threading.Thread
        Const WM_GETTEXT As Integer = &HD
        Const WM_GETTEXTLENGTH As Integer = &HE
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Int32, ByVal lParam As String) As Int32
        End Function
        <DllImport("user32.dll", CharSet:=CharSet.Auto)> Private Shared Sub GetClassName(ByVal hWnd As IntPtr, ByVal lpClassName As System.Text.StringBuilder, ByVal nMaxCount As Integer)
        End Sub
        <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> Private Shared Function FindWindowEx(ByVal parentHandle As IntPtr, ByVal childAfter As IntPtr, ByVal lclassName As String, ByVal windowTitle As String) As IntPtr
        End Function
        <DllImport("user32.dll", SetLastError:=True)> Private Shared Function IsWindowVisible(ByVal hWnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
        End Function
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        End Sub
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            Dim findItem As ListViewItem = ListView1.FindItemWithText(TextBox1.Text, True, 0, True)
            If findItem IsNot Nothing Then
                MsgBox("Burada değil!")
            End If
        End Sub
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            Me.CheckForIllegalCrossThreadCalls = False
            MyThreadExample = New Threading.Thread(AddressOf MyFirstSub)
        End Sub
        Sub MyFirstSub()
                Dim hWnd As IntPtr = IntPtr.Zero
                hWnd = FindWindowEx(IntPtr.Zero, hWnd, vbNullString, vbNullString)
                While Not hWnd.Equals(IntPtr.Zero)
                    Dim lgth As Integer = SendMessage(hWnd, WM_GETTEXTLENGTH, 0, Nothing)
                    Dim title As String = Space(lgth + 1)
                    SendMessage(hWnd, WM_GETTEXT, lgth + 1, title)
                    Dim wcn As New System.Text.StringBuilder("", 21)
                    GetClassName(hWnd, wcn, 20)
                    Dim isitvis As Boolean = IsWindowVisible(hWnd)
                    If isitvis = True Then
                        Dim lvi As New ListViewItem(wcn.ToString)
                    End If
                    hWnd = FindWindowEx(IntPtr.Zero, hWnd, vbNullString, vbNullString)
                End While
        End Sub
    End Class

    Friday, April 6, 2018 5:57 PM

All replies

  •  You are not using muti-threading,  you are only using one thread which continuously iterates through all windows.

     One problem I see is that you are accessing the ListView control which is in your Form's thread,  from the thread which you are iterating through the windows.  That is making a cross thread call and should never be done.  You should be Invoking a Delegate which accesses the listview on the Form's thread if you are going to use a secondary thread.

     A second problem I see is,  you are continuously iterating through all the windows and adding them to the listview and when the last window is found,  you are starting from the first window again.  This is continuously clearing and filling the listview over and over and  over,  non stop.  This is surely a reason it appears to be so slow.  However,  it is not that it is slow,  it is that you are flooding the form's thread with messages to clear and add items.  Basically,  you are causing the problem by overloading the listview with non-stop cross thread messages.

     I would recommend doing the following...  Put that code in a Sub and call the sub just once from the Form Load event.  Then use either WMI or the SetWinEventHook api function to have your form notified when a new window has been opened or closed.  When one is opened or closed,  you can call the sub again to update the list of windows.  This would make the code more efficient and would not flood the listview with non-stop messages.

     EDIT:  Perhaps if you explained why you need to find a window by its caption text,  we could suggest a better/shorter route to take.

    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Friday, April 6, 2018 9:31 PM
    • Proposed as answer by Mr. Monkeyboy Sunday, April 8, 2018 3:19 AM
    Friday, April 6, 2018 8:42 PM
  • Why should it be quicker? 

    Do you think that if you drive on an empty road with 6 empty lanes it goes quicker than on one lane.

    Moreover, multi threads have to be processed. Multi thread is only for 2 things useful:

    1. Keeping the desktop responsive (but then has to be protected that no wrong things are clicked)
    2. To do tasks which slowly parallel deliver data


    Friday, April 6, 2018 10:48 PM
  • Multi Threading is faster than a single thread for running multiple tasks at the same time such that the results can be obtained faster than if a single thread had to perform the same tasks linearly. I suppose Asynchronous operations would have the same result as threading with regard to keeping the UI from freezing but I don't know if asynchronous operations can run more than one "simultaneously". I suppose everything is time sliced by the OS though.

    Other than that threading will stop the UI from freezing as the UI will only be accessed by the thread in limited times rather than the UI thread being bogged down by work.

    La vida loca

    Sunday, April 8, 2018 3:19 AM