Hi Chris,
Based on what I could find on the web, I thought that the “cancel” variable on the schedule action when set to 1, would cancel the scheduled actions immediately. It appears to cancel only if the variable is 1 at the actual time the actions are executed.
What I want to do: have an action happen with a fixed delay after a behavioral action, given no intervening behavioral actions (i.e. display a stimulus 1s after fixation start given no break fixation intervenes). Schedule the first event. If I need to cancel on break fixation, cancel the first, and reschedule.
I have a test case showing that this doesn’t work, attached. Both the initial schedule and re-scheduled actions get run.
Is this intentional behavior, and if so any suggestions about how to achieve this? I suppose I could use an “if” action inside the scheduled actions, which runs the actions only if now() > someTimestamp. The main limitation here besides extra code is the time needed to run the scheduled actions many times.
Thanks,
Mark
Attachment: ReschedTest.xml (4.4 KB)
Hi Mark,
Based on what I could find on the web, I thought that the “cancel” variable on the schedule action when set to 1, would cancel the scheduled actions immediately. It appears to cancel only if the variable is 1 at the actual time the actions are executed.
Here’s what’s happening: Every time a scheduled action executes, it first checks whether the “cancel” variable is set to true. If it is, then the attached actions are not executed, and any subsequent repetitions are cancelled.
The problem in your test case is that after you set cancel_pulses
to 1, you change it back to 0 before the scheduled action tries to execute. Since, at the time of execution, cancel_pulses
is 0, the action is not cancelled. The workaround is to leave cancel_pulses
set to 1 and use a different “cancel” variable for your other scheduled task.
That said, it does seem like scheduled actions should behave as you expected, i.e. setting cancel to 1 should immediately cancel the actions. I’m not sure why I didn’t implement it that way in the first place. I’ll open a ticket for that change.
Cheers,
Chris
Also, I forgot to say that scheduled actions are best avoided in general. They probably shouldn’t exist at all at the XML level, but I guess someone had a compelling use case at some point.
What I want to do: have an action happen with a fixed delay after a behavioral action, given no intervening behavioral actions (i.e. display a stimulus 1s after fixation start given no break fixation intervenes). Schedule the first event. If I need to cancel on break fixation, cancel the first, and reschedule.
It sounds like this could be accomplished with a task system. What were your reasons for trying to use scheduled actions instead?
Chris
It sounds like this could be accomplished with a task system. What were your reasons for trying to use scheduled actions instead?
There are several intervening states in which the scheduled action could happen. Rather than cutting and pasting blocks of code into several places, I used a scheduled action.
But after actually implementing and debugging this I’ve decided it’s too complicated to implement this form of multithreading at the XML level - I think it will be too fragile for the future. I’m going to drop the scheduled action approach for now.
Did you have other concerns about scheduled actions that cause you to recommend against them?
Thanks,
Mark
Did you have other concerns about scheduled actions that cause you to recommend against them?
The fact that they run outside of the normal state system can be troublesome, e.g. un-canceled scheduled actions will keep executing even after the experiment stops. But the main issue is that multithreading is very difficult and should be avoided when possible.
Chris
The fact that they run outside of the normal state system can be troublesome, e.g. un-canceled scheduled actions will keep executing even after the experiment stops.
Yes. This is one of the things I wanted the “try/finally”-type action for. Others are: set the Matlab “sync” variable to zero, dequeue/stop any stimuli, call “stop_device_IO”, etc.
But the main issue is that multithreading is very difficult and should be avoided when possible.
Yes. Especially without any real synchronization primitives in the XML.
Thanks for the help and explanations,
Mark
This is one of the things I wanted the “try/finally”-type action for. Others are: set the Matlab “sync” variable to zero, dequeue/stop any stimuli, call “stop_device_IO”, etc.
Those last two aren’t necessary. When the state system stops,
- all queued stimuli are dequeued,
- all playing dynamic stimuli (e.g. drifting grating, movie) are stopped, and
- all I/O devices are stopped
The MATLAB window probably should stop collecting events, too. What else is in your cleanup list?
Chris
The MATLAB window probably should stop collecting events, too. What else is in your cleanup list?
Sound stimuli are not stopped, I believe.
We often send bytes to other equipment (either via network or via a parallel/serial cable) to signify the start and end of trials, start/end of dara acquisition etc.
Mark