Pause UI thread

Vader

Well-Known Member
Licensed User
Longtime User
How do I pause the UI thread?

I have a background thread that isn't receiving enough time, and DoEvents doesn't process anything in the background.

I don't want to come up with some complicated method to do it with a Timer either.

This is a roadblock to my app. Without this problem licked, it won't work.
 

mc73

Well-Known Member
Licensed User
Longtime User
Agreeing with Erel, I will just note that I had similar cases with yours, tried to avoid timers and asynchronous handling, only to find out quite soon, that I had an unstable process running.
 
Upvote 0

Vader

Well-Known Member
Licensed User
Longtime User
In almost all cases it is a bad idea to pause the main thread. You can pause it with a code such as:
B4X:
Sub Pause(TimeMs As Int)
 Dim t As Long = DateTime.Now + TimeMs
 Do While DateTime.Now < t
   DoEvents
 Loop
End Sub

If you are dealing with streams then you should use AsyncStreams and handle the relevant events.

Erel,

I AM using AsyncStreams, but I can't get to the data.

I am writing a VERY procedural app - talking to a car's diagnostic port - and I have already done it with Windows.

I don't know how I would incorporate timers and their Event-based code with something that is procedural.

:BangHead:

And before you say something like "oh, OBDII - just use [someone else's] code", this isn't OBDII.

EDIT: And your code example doesn't work for me. I am already doing that.

B4X:
Private Sub Wait(Milliseconds As Int)
   Dim EndTime As Long
   
   EndTime = DateTime.Now + (Milliseconds)   
   
   Do While DateTime.Now < EndTime      
      DoEvents   
   Loop
End Sub
 
Upvote 0

Eduard

Active Member
Licensed User
Longtime User
you can pause the UI with:
B4X:
ProgressDialogShow2("please wait",false)
Do procesdialoghide when the background thread is done.
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
How do I pause the UI thread?

I have a background thread that isn't receiving enough time, and DoEvents doesn't process anything in the background.

I don't want to come up with some complicated method to do it with a Timer either.

This is a roadblock to my app. Without this problem licked, it won't work.

Your problem is a bit vague without further explanation. So here's a theoretical answer:

From the Google doc: "Ensure you do any disk access, network access, or SQL access in a separate thread." Why? Because the result and duration of these accesses is uncertain. They can last a long time and let the system think that the application is hung or unresponsive (the famous ANR: application not responding).

That being said, how to stop the flow of the program and wait until the access is completed?

One of the ideas that come to mind is to add the following code to the main thread:
B4X:
MyFlag = false
do until MyFlag = true
   DoEvents
loop
...and to change the flag state in the event handler of the operation. Thus, the loop in the main thread waits until MyFlag becomes true and, in theory, should exit as soon as the event is received, but the problem is that most events are not fired by B4A during a DoEvents. It's obvious if you try to rotate the device while the loop is running. No Activity_Create, no Activity_Resume, and a weird display.

The simplest solution is to reorganize your code.
Example:
B4X:
Sub MyMainSub
   DoA
   WaitForAccess
   DoB
End Sub
...is split into two subs:
B4X:
Sub MyMainSub
   DoA
   WaitForAccess
End Sub
Sub AfterAccess
   DoB
End Sub
AfterAccess is called by the event handler of WaitForAccess when the operation is successful. In this way, you can wait for ages without risking ANR.

Fine, but this does not prevent the user from clicking buttons, scrolling lists, etc. As we saw, you cannot block the main thread while you wait for the access completion, and the main thread is the UI thread. So, what to do? One possible solution is to disable all views while waiting. Set Enabled to false or/and ignore click and touch events. You can also display a Cancel button.

A last useful thing: setting a Timer for timeouts. After a defined period, it cancels the access and displays an error message to the user.
 
Upvote 0

Vader

Well-Known Member
Licensed User
Longtime User
Thanks, but again, not helpful. I am working on a rewrite of my serial app to get around this problem.

Dave.
 
Upvote 0

Vader

Well-Known Member
Licensed User
Longtime User
You should explain what problem you get and provide some code, because for now we play a guessing game.

Understood. Here is the full explanation...

As I said in the last post, I need to rewrite my code so that I respond to the events rather than work the way it was originally designed. Not a great design choice for this app, but I have no other choice. I specifically designed this to work without events.

Oh well, that's just the way it is. :sign0148:
 
Upvote 0

Informatix

Expert
Licensed User
Longtime User
Understood. Here is the full explanation...

As I said in the last post, I need to rewrite my code so that I respond to the events rather than work the way it was originally designed. Not a great design choice for this app, but I have no other choice. I specifically designed this to work without events.

Oh well, that's just the way it is. :sign0148:

Thank you, I missed your other post.

I'm not an expert on bluetooth and serial things, so my help won't go further but, as I said to you recently, you have to forget the way you program with Windows and VB.
 
Upvote 0
Top