B4A Library Threading library

This library lets you run Basic4android Subs on separate threads to the main GUI thread. It also contains a Lock (semaphore) object that can be used for resource access arbitration and thread synchronisation.

Included is also an enhanced Exception object to give more information on any Exception caught. This can also rethrow those caught Exceptions and can create new Exceptions to throw.

EDIT :- Version 1.1 posted. See post #13 for details.
 

Attachments

  • Threading1.1.zip
    19.2 KB · Views: 7,226
Last edited:

andrewj

Active Member
Licensed User
Longtime User
The problem with that is that I then need to handle the "file skipped" case by coding an if/then/else case, which complicates the rest of the code. Handling this by generating a local exception and just swallowing it works quite well. Is there any way to "bubble up" the exceptions I want but not the others?
Thanks
Andrew
 

andrewj

Active Member
Licensed User
Longtime User
Thanks.

I'll try working up an extract of my code for a separate thread as you suggest.
Andrew
 

kiki78

Active Member
Licensed User
Longtime User
Hello Agraham,

Just a little remark.
Thread variable are always mark by IDE as not initialized (warning #11).
Perhaps this is due to unconventional naming Initialize sub as Initialise.

Regards
 

tipallandgo

Member
Licensed User
Longtime User
Hi, I just noticed something. If I do an obfuscated release build, the sub I'm using for the thread is not detected.
 

TheWind777

Active Member
Licensed User
Longtime User
It would be nice if the mis-spelled .Initialise were changed to the proper .Initialize, as it should be.

In the upper-right hand corner the B4A editor keeps giving an error for each new thread instance because it thinks they haven't yet been initialized.

I always get every one of those green errors to go away so I know things are all proper. Because of that error, I can't get it to stop and can't see the real errors that might be detailed there.
 

Thraka

Member
Licensed User
Longtime User
I don't fully understand how we use ExceptionEx with LastException to get more detailed information. Is there an example somewhere? If I just make a new ExceptionEx with my own personal message is Cause automatically filled with LastException or something?
 

SteveTerrell

Active Member
Licensed User
Longtime User
Hi, I notice that the Stop button seems to cause an exception (only the original thread that created a view hierarchy can touch its views). presumably because the Interrupt in the stop click code results in the thread ended sub being called where there is a message box.

Is this by design?
 

SteveTerrell

Active Member
Licensed User
Longtime User
Ok, commented out the message box and that's not the cause of the problem. Here is the log.

B4X:
Installing file.
GC_CONCURRENT freed 458K, 6% free 9341K/9880K, paused 2ms+5ms, total 73ms
WAIT_FOR_CONCURRENT_GC blocked 50ms
** Activity (main) Pause, UserClosed = false **
PackageAdded: package:anywheresoftware.b4a.agraham.threaddemo
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
java.lang.RuntimeException: java.lang.InterruptedException
    at anywheresoftware.b4a.agraham.threading.Threading$SemaphoreWrapper.WaitFor(Threading.java:583)
    at anywheresoftware.b4a.agraham.threaddemo.main._threadsub1(main.java:660)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.agraham.threading.Threading$1.run(Threading.java:216)
    at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.InterruptedException
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedNanos(AbstractQueuedSynchronizer.java:1016)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.tryAcquireSharedNanos(AbstractQueuedSynchronizer.java:1304)
    at java.util.concurrent.Semaphore.tryAcquire(Semaphore.java:380)
    at anywheresoftware.b4a.agraham.threading.Threading$SemaphoreWrapper.WaitFor(Threading.java:580)
    ... 5 more
java.lang.RuntimeException: java.lang.InterruptedException
    at anywheresoftware.b4a.agraham.threading.Threading.Sleep(Threading.java:151)
    at anywheresoftware.b4a.agraham.threaddemo.main._threadsub2(main.java:715)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:515)
    at anywheresoftware.b4a.agraham.threading.Threading$1.run(Threading.java:216)
    at java.lang.Thread.run(Thread.java:841)
Caused by: java.lang.InterruptedException
    at java.lang.VMThread.sleep(Native Method)
    at java.lang.Thread.sleep(Thread.java:1013)
    at java.lang.Thread.sleep(Thread.java:995)
    at anywheresoftware.b4a.agraham.threading.Threading.Sleep(Threading.java:148)
    ... 5 more
** Activity (main) Pause, UserClosed = true **
** Activity (main) Resume **
 
Last edited:

SteveTerrell

Active Member
Licensed User
Longtime User
Ok thanks again, i made the mistake of thinking it was ok to run under the debugger but do not use breakpoints etc.

In release mode there is nothing in the log and the Thread2 Ended message box says Exception: java.lang.InterruptedException followed by the same thing for Thread 1

I guess that is as it should be?
 

SteveTerrell

Active Member
Licensed User
Longtime User
Don't show a msgbox from a different thread. It will fail.

Use Log instead.

Ok, the program is just as i downloaded it from post 1 so does that need changing or is it the case that the Interrupt is an exception which can be ignored?

B4X:
Sub Thread1_Ended(fail As Boolean, error As String) 'An error or Exception has occurred in the Thread

    Msgbox(error, "Thread1 Ended")
End Sub
 
Last edited:

pmg

Member
Licensed User
Longtime User
The threading example works when compiling without with the debugger.
With the debugger, when I press the Start button, I get:
Thread1 Ended
Exception: wrong number of arguments; expected 4, got 0
 

Sberla

Active Member
Licensed User
Longtime User
Hi, hope that somebody can help me with this problem, i cant start the thread's subs, what is wrong?

Code:

Sub WriteTextWriter
Dim args(0) As Object
Thread1.Name = "B4A Thread 1"
Thread2.Name = "B4A Thread 2"
Thread3.Name = "B4A Thread 3"
Thread1.Start(Null,"threadsub1",args)
Thread2.Start(Null,"threadsub2",args)
Thread3.Start(Null,"threadsub3",args)
End Sub

Sub Threadsub1
instructions
End Sub

Sub Threadsub2
instructions
End Sub

Sub Threadsub2
instructions
End Sub
 

kiki78

Active Member
Licensed User
Longtime User
Hi Sberla,

You must declare Thread1 in Sub Globals then initialize it somewhere : Thread1.Initialise("Thread1").

I suggest you insert underscore "_" in your Thread sub name, this avoid rename when you compile obfuscated.
For example, name it "Thread1_Fcn"
B4X:
Private Sub Thread1_Fcn(ParamObj() as Object)
    'Your Code
End Sub

I recommend also to declare event sub "Ended", that is call at end of thread end give some information in case of error.
B4X:
Private Sub Thread1_Ended(endedOK as Boolean, error as String)
    If endedOK = False Then
        'Log Error message
    End If
End Sub

The first parameter for Start is class object that contain your thread sub. Typically this can be Me if your start call is in the same class than your thread function.
B4X:
    Thread1.Start(Me, "Thread1_Fcn", args)
Please try all of this and give us result.

Regards
 
Top