title: Is TThread.Synchronize evil / stillborn?
body: <p>I got an impression that a thread which should be at least a little controllable from main thread must not use <code>Synchronize()</code> at all: any attempt to do this almost immediately results in deadlock in one case or another.</p>
  
  <p>As a consequence, onTerminate event should be avoided also as it's called using Synchronize.</p>
  
  <p>For example, I have a thread which does some hard background work. I want to watch its progress in status bar and be able to stop it 'gracefully' if user pressed close button.</p>
  
  <p>I can't use <code>FreeOnTerminate := true</code>, because as thread was started I must not call any of its methods at all: at any moment it might be destroyed and I get access violation (or corrupt something completely).</p>
  
  <p>So, thread destruction is main thread's responsibility. It would be logical to do all the 'finishing' job in some sort of DoTerminate procedure and point onTerminate event to it. But that's deadlock: we can't free the thread from DoTerminate because in TThread.Free there is WaitFor which can't complete before synchronized onTerminate event finishes.</p>
  
  <p>Not just OnTerminate: if worker thread has any of Synchronize calls in it (for example, it wants to inform us that some percents of work was done etc), there is possibility of deadlock if at this very moment main thread is going to do smth with worker thread: they block each other!</p>
  
  <p>So, in my understanding, the only way of using Synchronize is to delegate all the calls to worker thread side! For example, we make it with <code>FreeOnTerminate := true</code> and it sometimes uses Synchronize() to tell us its progress, or that it's done already and going to be destroyed. And only inside these procedures we're able to control it, but it makes graceful shutdown 'at will' almost impossible or overcomplicated.</p>
  
  <p>Am I missing something (some internal workings which help to overcome these deadlocks somehow)? Because I'm a little surprised: Synchronize() is one of first methods described in Delphi multi-threading manuals. Is it really so useless?</p>