I think I will try @Mr.Madguy's proposal without any threads to see how it will look like and how long exactly processing an image might take, and then I will search a harder solution if necessary.
I think that this will I have problems mostly with SMB (at least DobleCommander hangs for minutes, when trying to access a switched off/disconnected SMB source). But that is not an issue for this topic.
No, you still can use threads. Threads are actually required for some tasks, such as tasks, that require thread blocking. What I try to say, is that back in old days application had to divide long tasks into small pieces and constantly return control to OS, so other applications wouldn't be locked. Funny thing, but even for hardware multitasking - it's still the best way of doing things. That's why applications still use exactly the same message-based system, as back in 3.0/3.1 days, instead of being constantly active and relying on hardware multitasking to sort things out. You just can't terminate thread at any moment, as it's the same, as terminating process via Task Manager - some objects would be in undefined state in this case. You have to exit thread procedure in order to terminate it properly. So you still need to divide your task into small pieces and constantly check, if Terminated property isn't True and exit thread, when it's the case - not rely on OS, i.e. just execute and terminate thread, when you want.
Best solution: to have some worker thread pool, to divide your long tasks into small pieces and send them to thread manager, that will assign them to worker threads and process one by one. But if it's way too hard for you - try to execute every task in separate thread, but divide it into smaller task and constantly check, if this task isn't abandoned. Second variant isn't good in common case, cuz it can cause number of simultaneous threads inflation, that is bad thing, as OS core would struggle in this case.