Yes, that is expected because of the way USB requests are handled when threading is off.
My first recommendation is to add
SYSTEM_THREAD(ENABLED);
at the top of the file, not in a function. This decouples system actions from the user firmware (mostly) and is what I’d recommend.
Another way is to not write any code that blocks returning from loop(). This would typically involve finite state machines, which your students may not be up to yet.
The final way is that whenever you have a blocking loop, either call Particle.process() in the loop, or delay(1);.
Rick - thank you. I assumed a small delay in the loop would help, but I have been trying to train my students to not use delay() in their code as they tend to like to add delays an then don’t understand why an input isn’t registering. We’ll go the SYSTEM_THREAD(ENABLED) route.