Thread Still Blocking UI

  1. 2 weeks ago

    erin j

    Apr 14 Pre-Release Testers, Xojo Pro

    Clearly I am missing something, but here is the setup:

    subclass of thread (call it mThread) takes sql parameters and a query to run as arguments.
    It creates its own connection using MySQLCommunityServer object, then runs the query. It stores the result in a property, when the query is done the isFinished flag of the mThread class is set to true.

    A window has a an mThread property and a timer checking the isFinished flag.

    As a point of testing I never actually access the results of the mThread property or do any UI updating.
    The window creates a new mThread with a long running sql query, and starts the timer. Now the UI locks up and I get the beach ball (using MAC). Changing the timer period does nothing (as expected). Changing the query to a faster query is the only thing stops the UI from locking.

    What is going on? This seems like the opposite behavior of a thread. Now to be clear, the thread has its own connection the the database, it does not share that with anything else.

  2. Andrew L

    Apr 14 San Francisco, CA, USA

    Make sure that you're performing the query in the Thread.Run event. Only code called from within the event is run on a separate thread.

  3. Jean-Yves P

    Apr 14 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    the database queries are NOT threaded.
    you must use the limit and offset keywords to reduce the length of your query
    or
    use MBS database plugins that are thread friendly.

  4. erin j

    Apr 14 Pre-Release Testers, Xojo Pro

    This is the run event:

    dim rs as RecordSet = connection.SQLSelect(searchQuery)
    dim resultString as string
    if rs <> NIl then
      while not rs.EOF
        for ii as integer = 1 to rs.FieldCount
          if ii <> 1 then
            resultString = resultString + "," + rs.IdxField(ii).StringValue
            
          else
            resultString = rs.IdxField(ii).StringValue
            
          end if
          
        next
        
        results.Append(resultString)
        rs.MoveNext()
        
      wend
      
    else
      errorMessage = connection.ErrorMessage
      
    end if
    
    connection.Close()
    isfinished = true
  5. erin j

    Apr 14 Pre-Release Testers, Xojo Pro

    @Jean-YvesPochez, You are saying that even if a thread has its own connection it will still block the main execution thread?

  6. Jean-Yves P

    Apr 14 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    @erin j @Jean-YvesPochez, You are saying that even if a thread has its own connection it will still block the main execution thread?

    yes if you make a long sql query within a thread, this blocks the UI. this is true if you use xojo build in database plugins.

  7. James S

    Apr 14 Pre-Release Testers, Xojo Pro

    Since the threading is cooperative, it’s up to the threads to yield time to other threads. In the case of normal Xojo code the threads yield every time there is a loop boundary and in many other places too I think. Once you call out to some library or other function, such as the running of the query, unless those functions are specifically written to yield time back to the other threads then it will block the entire app just as if you hadn’t bothered to put it into a thread at all. Unfortunately the database stuff is mostly like this. If using the MBS plugins is not an option then you should break your query up into blocks as Jean-Yves Pochez suggested. Then run it in a loop to get through all the data and the very act of returning control to some Xojo code and looping will make sure the other threads get serviced, though you can specifically perform a yieldToNextThread in your loops if you want to experiment.

    And I think you should definitely consider putting in a feature request for the built in Xojo plugins to add some proper support for threads as they make such things very difficult right now. There might even already be one...

  8. Christian S

    Apr 14 Pre-Release Testers, Xojo Pro, XDC Speakers Germany

    In MBS Xojo SQL Plugin , we do have ConnectMT, SQLSelectMT and SQLExecuteMT function to run thread friendly.

  9. James S

    Apr 14 Pre-Release Testers, Xojo Pro

    @ChristianSchmitz In MBS Xojo SQL Plugin , we do have ConnectMT, SQLSelectMT and SQLExecuteMT function to run thread friendly.

    For the record I've been using Christians plugins since forever and can whole heartedly recommend them as a solution to this problem and many others. Well worth the money if it’s a viable option. That doesn’t mean you shouldn’t bug Xojo with an official feature request to properly support their own threading model in the database plugins though ;)

  10. last week

    Tobias B

    Apr 15 Pre-Release Testers, Xojo Pro Bern, Switzerland

    @James S unless those functions are specifically written to yield time back to the other threads then it will block the entire app just as if you hadn’t bothered to put it into a thread at all. Unfortunately the database stuff is mostly like this.

    hm - IIRC years ago the built in Database Plugins all had a MultiThreaded property to control if they shall yield. As this costs performance, they then were refactored so that this behaviour is automatically detected. Just PostgreSQLDatabase has kept it's MultiThreaded property. The documentation for MySQLCommunityServer even states

    "SQLSelect and SQLExecute statements do not block when called from within Threads."

    If they do, I'd count this as an Bug that should be reported. I did so with PostgreSQLPreparedStatement which did block despite MultiThreaded in Feedback Case #37806 and got it fixed within a comparable short period of time.

  11. Jean-Yves P

    Apr 15 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    yes there is a MultiThreaded property, but it is not used it seems.
    I already made a feedback some times ago, then as it was not corrected at all I programmed differently ...
    it is definitely a bug, and one that will certainly never be corrected ...

  12. Tobias B

    Apr 15 Pre-Release Testers, Xojo Pro Bern, Switzerland

    @Jean-YvesPochez yes there is a MultiThreaded property, but it is not used it seems.

    are we talking about MySQLCommunityServer here? According to the Docs the property was in use from 2011r1 to 2013r3 only.

    I already made a feedback some times ago, then as it was not corrected at all I programmed differently ...
    it is definitely a bug, and one that will certainly never be corrected ...

    That sounds quite disappointed. To my experience, if a bug is really a problem for you, Xojo will fix them in the end, even if relatively specific, but lobbying for it takes some time and effort. If you need a quick solution, you can head over to MBS, but this possibility should not be an excuse for not fixing upstream bugs in the end ;)

  13. Sascha S

    Apr 15 Pre-Release Testers, Xojo Pro Germany

    I thought the issue is with Connecting to the Server only, because i tend to prefer short/quick querrys. And i created a FR for the connect issue in January 2019: Feedback Case #54692

  14. Tobias B

    Apr 15 Pre-Release Testers, Xojo Pro Bern, Switzerland

    @SaschaSchneppmueller I thought the issue is with Connecting to the Server only

    the code posted by the OP did not contain the db.Connect within the Thread.Run so I assumed this is done earlier. But yes - as of current there is no promise about db.Connect being thread friendly.

  15. Jean-Yves P

    Apr 15 Pre-Release Testers, Xojo Pro Europe (France, Besançon)

    @Tobias B That sounds quite disappointed. To my experience, if a bug is really a problem for you, Xojo will fix them in the end, even if relatively specific, but lobbying for it takes some time and effort. If you need a quick solution, you can head over to MBS, but this possibility should not be an excuse for not fixing upstream bugs in the end ;)

    I programmed the thing differently (using limit and offset) and it worked well without threads ...
    so I did not hassle Xojo to correct it !

  16. I overcome this actually by using

    this code in the threaded process

    Dim param(-1) as variant
        param.Append(DataToUpdate)
        param.Append(DataToUpdate2)
    
        Xojo.Core.Timer.CallLater(1, AddressOf AddToList, param)

    and create new method with this to update UI
    AddToList(data as auto)

      dim ListDetail() as variant = data
    
      listbox1.addrow(cstr(ListDetail(0))
    etc...)

or Sign Up to reply!