With Cocoa it is no longer posible to access a UI element from a thread, actually it has been always unrecommended. Ok.
I knew that so for several apps I used events and an event handler. The event handler is an object with methods that call events. An event handler class is created for a window and pass to the thread. The thread then call events to exchange stuff with the window.
It has always work fine and seems to be reliable. With most RB/Xojo Release it used to work fine with Cocoa as well. Since last Xojo release I simply get a ThreadAccessingUIException. Is accessing a UI element thru events forbidden as well? If so, what is the reason?
[quote=112409:@Stanley Roche Busk]With Cocoa it is no longer posible to access a UI element from a thread, actually it has been always unrecommended. Ok.
I knew that so for several apps I used events and an event handler. The event handler is an object with methods that call events. An event handler class is created for a window and pass to the thread. The thread then call events to exchange stuff with the window.
It has always work fine and seems to be reliable. With most RB/Xojo Release it used to work fine with Cocoa as well. Since last Xojo release I simply get a ThreadAccessingUIException. Is accessing a UI element thru events forbidden as well? If so, what is the reason?[/quote]
If you call the method directly from the thread then it looks to me as part of the thread.
Why not use the action event of a timer instead ? A mode single event with a period of 1 that you enable from the thread will do the trick. You can even use a variable to enable a select case in the Action event to execute different subroutines according to what you need. Of call that from the events where you sued to modify the UI directly.
The thread calls events, not methods.
My application are quite complex, one of then even get and set listbox cells, thru events, not methods. I know the timer trick and will use it if I have no choice, that means a lot of work. Before that I want to make sure threads can’t use events either.
An event is nothing else than a method.
Sorry, Stanley. Time to roll up the sleeves and get to work. A thread cannot touch the UI, direct call, method, event, doesn’t matter.
Events are “risen” not called. Depending on the architecture they just go to queue waiting to be “collected” and processed.
Xojo seems not queue events, just process then right away when they are risen, so, they are processed in the same context (thread). UI needs to be accessed from the main thread, and the only way in Xojo to switch the context is using a timer. The timer event rises in the main context.
Events are called. They are regular methods. Besides the naming like Event_Open() for the Open event there is no difference to a regular method. The IDE just treats them differently.
In the past you could get away with it even though it lead to some obscure crashes in apps that accessed UI from a thread. I was as guilty as many others since I could get away with it even though it was discouraged. I think Xojo took the right approach in forcing the issue. It’s a bit more work on our part but the result is a more stable application without the spurious random crashes.
Look in the examples Desktop/UpdatingUIFromThread/ directory. The Task example is a very good way to accomplish the same thing but in a safe way. Now that we’ve switched to using it I like it a lot but it does take a little time to get used to it.
If you call something, its a method, if the processing loop calls it in your place, because “something” occurred, its an event. The tool Xojo offers to raise events is RaiseEvent() http://documentation.xojo.com/index.php/RaiseEvent
The question was, if there is a difference between events and methods regarding accessing the UI from threads. No, because events are methods (internally in the framework).
Yes, an event is raised, and a method called. But the mere mechanism of AddHandler is :“Used to delegate the responsibility of handling an event to a method.”. Ultimately, when an event is raised, execution is delegated to a method.
Frankly, I do not care about these academical differences. The original question was :
[quote=112409:@Stanley Roche Busk]Since last Xojo release I simply get a ThreadAccessingUIException. Is accessing a UI element thru events forbidden as well? If so, what is the reason?
[/quote]
Proof being in [the tasting of] the pudding, you discovered it raises an exception. The reason probably lies in the fact that the Cocoa framework forbids it.
Now if you want to use the latest version of Xojo, you need to find the easiest solution to adapt your code, which seems to be the use of a timer. Or maybe the Task class. The other solution is to revert to an older version of RB/Xojo.
You will be able to compile the project with an older RB/Xojo version, but on OS X the application will crash on newer versions (I think starting with OS X 10.8).
Personally, I would modify my app to work under the latest version of Xojo anyway.
Adaptation is key to survival. Dinosaurs should have known better
You may want to check out this thread especially Normans explanations:
https://forum.xojo.com/11717-are-observers-a-thread/p1#p86661
[quote=112415:@Stanley Roche Busk]The thread calls events, not methods.
My application are quite complex, one of then even get and set listbox cells, thru events, not methods. I know the timer trick and will use it if I have no choice, that means a lot of work. Before that I want to make sure threads can’t use events either.[/quote]
The top of the call stack is still the thread
Whether its an event or method doesn’t make a difference
@Stanley Roche Busk - unfortunately, this is the only solution moving forward. I’ve very happy that I made the changes to my code back around 2011’s Cocoa beta releases.
You’ll also find it’s true for any other language that supports threading. I see the exact same issue with Python and Java, but Lambda’s (Closures) simplify it a little.
Sprinkling 1MS timers that call methods (callbacks) is very “code effective” as well since you can change your method and not need to track down other locations with similar code. A properly written callback method can handle many cases and provide a single point of management.
Also, it’s even made my Carbon compiles in 2012r2.1 more stable for older platforms (some of our tools support back to 10.4.11).
Sorry, you are mistaken. While some events are actually system events - like timers and sockets - most are not. Especially any event you add yourself. They are called in-line, not as part of the event loop. Event <> System Event.
RaiseEvent is just syntactic sugar to disambiguate where you have a method and an event with the same name. RaiseEvent is still a method call.
Event is event, system event is a kind of event. The fact you can call methods used to respond to events does not make an affirmation like “methods that call events” correct. Event = Something that happens, Method = a way of doing something. Events are “caused” (risen) not called. You can say things like I called the open() method of the class (done directly), or I fired or raised the event open() (done indirectly).