Unhandleable errors in Preemptive Thread

my application instantiates 100 cooperative threads
it works but in this configuration 100 threads are a queue of 100 operation to main app thread
i’m tring to convert the app to use preemptive threads

in the all part of the code there is try …catch construct included the code of inside thread
i have set the stacksize of thread to 2048000
i have changed the kind of thread from cooperative to preemptive

if i’m in debug mode the app work few minutes then stops but do not shows errors,
no handed errors (intercepted by try catch structure) and no unhandled error intercepted from unandledErrorEvent of app

in code of the thread there is no referements to app variables or referements to part of the gui elements
all of variables , sub and functions are inside the thread scope

before call threads start method i set the value of thread proprierty (idRecord) , this porperty contains the id of the record of a mysql db’s table that thread must manipule.

then the thread open new db connection, retrieve this record, then make update of this row , then close db connection

the app works, but crash without handlable errors

how can i find the problem?
there is a best pratice ?

The safest way to debug a preemptive thread is logging debug messages and not stopping the thread. Stopping a really independent, and planned to be unstoppable thread, to debug it, will put things in an unpredictable state.

ok thanks for the information

Printing thread activity info inside the debug window, with 100 threads working continuously becomes unreadable.

However, I don’t understand why the try/catch construct inside therad…is unable to intercept the error

I’m not understanding why you need 100 threads. What you described seemed a simple task that could be solved by just one preemptive thread and a queue and that connection could be kept open all the time.

How’s that try/catch code?

I’m not understanding why you need 100 threads. What you described seemed a simple task that could be solved by just one preemptive thread and a queue and that connection could be kept open all the time.

If I want parallel processing I can’t use a single thread otherwise I serialize the processing and if one of the tasks in the series stops, it will stop all the tasks in the queue.
So I need parallel activities and each with its own connection, to avoid the bottleneck or that a clogged connection to the database blocks all the rest of the operations.

in various

Try

Catch

end try

it contains all the code that reads and writes to the database, which certainly causes errors, especially due to lock table timeout events

the problem is that try catch doesn’t catch any errors, so I can’t find a way to handle the error which then crashes the app

Try only having the number of preemptive threads match the number of cores on the machine. I usually use System.CorCount-1 so as not to saturate the machine, and then create a queue that the app can pull from.

1 Like

A pool of 4 preemptive threads consuming a queue should be sufficient.

2 Likes

Make the amount of thread maximum to the amount of cores (or cores -1) System.CoreCount so that you don’t overload the system too much.

1 Like

Additionally you may want to add something to your thread that sends back the exceptions with messages:

Thread.Run

Try

// your code

Catch e As NilObjectException
Var ed As New Dictionary
ed.value("excetion") = "NilObjectException"
ed.value("message") = e.message
ed.value("errorCode") = e.ErrorCode
Self.AddUserInterfaceUpdate(ed)

Catch e As InvalidArgumentException
Var ed As New Dictionary
ed.value("excetion") = "InvalidArgumentException"
ed.value("message") = e.message
ed.value("errorCode") = e.ErrorCode
Self.AddUserInterfaceUpdate(ed)

End Try

This may help getting the exceptions to a certain level in the UserInterfaceUpdate event

Have a look at the ThreadPool example in the IDE’s examples. The MVPs (especially @Kem_Tekinay) put a lot of time and effort in to this example to make using preemptive threads easier.

3 Likes

it contains all the code that reads and writes to the database, which certainly causes errors,

have you tried CriticalSection or Semaphore around database access?

https://documentation.xojo.com/api/language/criticalsection.html
https://documentation.xojo.com/api/language/semaphore.html

1 Like

Try

// your code

Catch e As NilObjectException
Var ed As New Dictionary
ed.value(“excetion”) = “NilObjectException”
ed.value(“message”) = e.message
ed.value(“errorCode”) = e.ErrorCode
Self.AddUserInterfaceUpdate(ed)

Catch e As InvalidArgumentException
Var ed As New Dictionary
ed.value(“excetion”) = “InvalidArgumentException”
ed.value(“message”) = e.message
ed.value(“errorCode”) = e.ErrorCode
Self.AddUserInterfaceUpdate(ed)

End Try

this is not possible,
when multiple preemptive threads are running the try/catch construct does not work and does not catch any errors, the application ends badly (at least for me at least in debug)

i guess you are choking the system. Preemtive threads should not be used more that the system allows for.

Also if there is a crash (not exception) then you see the :bomb: icon in the debugger. That happens if there was hard crash (not exception, again) in a preemtive thread.

I guess your code would work better if you run (1 to corecount) as a pool. There is no parallelisation guarantee so this wouldn’t matter anyway.

If you run too many threads (or sockets or any other resource for that matter) you may end up with hard crashes. Also if you call the same instace of ‘some’ (really any) object in 2 threads at the same time then :bomb: will show up… and your out of luck.

There are so many things you need to prepare in advance, you can’t just change the switch and expect it to work.

1 Like