threads & anonymous methods

I had a funny idea this weekend, I was looking for a way to multithread a part of my code without having to break my code.
Using an anonymous method the thread is able to access the local variables of the method that executes the thread.
The trick is very simple and allows great flexibility in the code.

type
  TRefProc = reference to procedure;

function Thread(const proc: TRefProc): THandle;
  function run(const proc: TRefProc): Integer; stdcall;
  begin
    proc;
    Result := 0;
  end;
begin
  CreateThread(nil, 0, @run, PPointer(@proc)^, 0, Result);
end;

procedure DoIt;
var
  done: THandle;
begin
  done := CreateEvent(nil, True, False, nil);
  try
    Thread(procedure
    begin
      sleep(2000);
      SetEvent(done);
    end);
    WaitForSingleObject(done, INFINITE);
  finally
    CloseHandle(done);
  end;
end;

4 Responses to “threads & anonymous methods”

  1. coder_buzz says:

    Haha… nice one mate, good small “chunk” of code :D
    Where you put CloseHandle(ThreadHandle) to release thread resource :p

  2. admin says:

    If I do that, I have an external exception C0000008, it means that the handle is invalid. I assume it is not necessary.

  3. Codu says:

    @coder_buzz :
    1. You dont put “CloseHandle(ThreadHandle)” to release the thread resources, you put “CloseHandle(ThreadHandle)” to close the thread’s handle. You (should) put ExitThread(…) to release the thread’s resource (the one and only: stack).

    @Henri :
    2. I have D7, but still, I’m not sure that a thread can access a variable of another thread … If “done” is at global scope, it should work, but not at local scope = the stack of the function.

  4. AdamWu says:

    This is smart! But here is a catch:

    The compiler can out smart you and overwrite storage space of the anonymous method, while the child thread still running!

    From the calling thread’s point of view, when Thread() function returns, the “proc” anonymous method is already out-of-scope, and can be reclaimed for other uses.

    According to MSDN documentation:
    The thread object remains in the system until the thread has terminated and all handles to it have been closed through a call to CloseHandle.

    So, a call to close handle is needed. (It is possible that you are getting C0000008 because of the catch!)

Leave a Reply