B4J Question Using Thread in B4J Application

Discussion in 'B4J Questions' started by swissmade, Feb 9, 2015.

  1. swissmade

    swissmade Active Member Licensed User

    Hi all,

    I wondering whats happening, when I initialize the same Thread again.
    Is Java handling this as a new thread or is the Thread overwritten.
    Or must I declare the Threads in a Array???

    Also how can I get the Thread ID of the Running Thread.
    Attached a small Test prog showing a Process Bar set value by 5 threads.
    Thanks for Helping me out here.
     

    Attached Files:

    Last edited: Feb 9, 2015
  2. Erel

    Erel Administrator Staff Member Licensed User

    There are several mistakes in your code. Remember that only the main thread is allowed to access UI elements.

    In most cases it is a mistake to use the Threading library. Why do you need it?
     
  3. swissmade

    swissmade Active Member Licensed User

    In my Test program I see one mistage that I dont use RunOnGuiThread.
    I need some Thread to avoid the UI to freeze in long Functions with some loops to read a resultset and do some checks.
    This can be many Records and have to go without freezing the UI.
    The Program has to keep running for new input from Users for a Access control system.
    I try this with the threading Library because DOEvents not exist in Java.

    I hope you can help me out here.
     
  4. Erel

    Erel Administrator Staff Member Licensed User

    The correct solution is:
    1. Make sure that your SQL queries are optimized and that they use indices.
    2. Use ExecQueryAsync to use a background thread and avoid freezing the UI.
     
  5. swissmade

    swissmade Active Member Licensed User

    The Querys are indices.
    In some situations I can not make use of ExecQueryAsync because there has to be waited on the result.
     
  6. Erel

    Erel Administrator Staff Member Licensed User

    Optimized queries should be very fast.

    Anyway you can execute the first query and then when QueryComplete is raised execute the next one.
     
  7. swissmade

    swissmade Active Member Licensed User

    Nice idea thanks.
     
  8. swissmade

    swissmade Active Member Licensed User

    Erel,
    The reason the GUI freeze is the Update for a TableView.
    I always test if something has changed if not we need no update.
    All the Query's in this process take about 100ms what is fine and fast.

    Update the TableView with InsertAT(0) take about 400-700ms.
    I only Insert the records not exist in the Tableview.
    This time is too long because there already new entry's waiting for access.

    Maybe you have a idea how I can solve this.

    Thanks for your help.
     
  9. Erel

    Erel Administrator Staff Member Licensed User

    Only the main thread can add items to TableView. So background threads will not help here.

    How many items are you adding?

    Have you tried to set all the items at once by setting TableView.Items = NewListOfItems ?
     
  10. swissmade

    swissmade Active Member Licensed User

    Hi Erel,

    Somehow I can not get to your Page.
    So I answer your questions this way.
    There can be 1 but also 1000 items to add to the TableView.
    If the Table is empty then all records from this day has to be shown in the TableView.
    This is a access control system with RFID Tags, Fingerprint and Barcode readers.
    I will try to first add the records to a list in memory and then if all is collected I add the items to the TableView and show them.

    Many many thanks for your help.
     
  11. jmon

    jmon Well-Known Member Licensed User

    What I do in cases like that is something similar to that:
    Code:
    Sub Process_Globals
        
    Private fx As JFX
        
    Private MainForm As Form
     
        
    'I create a map that holds the status of the queries:
        Private QueriesStatus As Map = CreateMap("Query1"False"Query2"False"Query3"False)
    End Sub

    Sub AppStart (Form1 As Form, Args() As String)
        MainForm = Form1
        MainForm.RootPane.LoadLayout(
    "Main"'Load the layout file.
        MainForm.Show
     
        StartQueries
    End Sub


    Sub StartQueries
        
    Dim sq As SQL
        
    'Job 1
        sq.ExecQueryAsync("Query1""SELECT * FROM customers;"Null)
        
    'Job 2
        sq.ExecQueryAsync("Query2""SELECT * FROM countries;"Null)
        
    'Job 3
        sq.ExecQueryAsync("Query3""SELECT * FROM planets;"Null)
    End Sub

    Sub Query1_QueryComplete (Success As Boolean, Crsr As ResultSet)
        
    If Success Then
            
    'Do my thing with this query
            '...
         
            
    'Save the status as true (finished):
            QueriesStatus.Put("Query1"True)
     
            
    'Then check the status of the other queries:
            CheckStatus     
        
    End If 
        sq.close
    End Sub

    Sub Query2_QueryComplete (Success As Boolean, Crsr As ResultSet)
        
    If Success Then
            
    '... something
            QueriesStatus.Put("Query2"True)
            CheckStatus     
        
    End If    
        sq.close  
    End Sub

    Sub Query3_QueryComplete (Success As Boolean, Crsr As ResultSet)
        
    If Success Then
            
    '... something
            QueriesStatus.Put("Query3"True)
            CheckStatus     
        
    End If  
        sq.close    
    End Sub

    Sub CheckStatus
        
    If QueriesStatus.Get("Query1") = True AND _
            QueriesStatus.Get(
    "Query2") = True AND _
            QueriesStatus.Get(
    "Query3") = True Then
         
            
    'All the queries are finished.
            '...
        End If 
    End Sub
    That way you get all 3 queries running together, and "CheckStatus" is only executed when they are all finished.

    Edit:
    By the way, what kind of controls do you have in your TV? In this test http://www.b4x.com/android/forum/threads/memory-leak.49751/#post-312592
    I had 1000s of items refreshed in under 200ms
     
    Last edited: Feb 11, 2015
  12. swissmade

    swissmade Active Member Licensed User

    Hi Jmon,
    Very nice you think with me many thanks for this.
    I use it already a similar way.
    What I do is calling this Function every Time and Fetch the result in QueryComplete.
    I also give the Query a TasID so I need one Function to fetch the Result.
    The Checkstatus is a good idea.
    See Code
    Code:
    Public Sub StartQuery(strMYSQL As String, Task As Int)
    Try
        
    If strMYSQL.Contains("SELECT"Then
            strMYSQL = strMYSQL.Replace(
    "SELECT""SELECT " & Task & " AS QueryID, ")
        
    End If
        
    If strMYSQL.Contains("COUNT") = False AND strMYSQL.Contains("SELECT") = True Then
            Functions.LastQuery = strMYSQL 
    'Check for Select Query
        End If 
        Functions.ConnectToUSERSCREEN
    '*********************************************************************************** 
        Functions.SQLUSERSCREEN.ExecQueryAsync("SQLRespond", strMYSQL, Null)
    '*********************************************************************************** 
    Catch
        Functions.WriteErrorLog(
    "Last error in StartQuery Main" & LastException.Message )
    End Try
    End Sub
     
    Last edited: Feb 11, 2015
Loading...
  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice