You can look here to learn about threads:
http://wiki.freepascal.org/Multithreaded_Application_TutorialThreads are a bit like a TTimer but then different.
You saw that sleep(1000) and RecvString(1000) "hangs up" your program. Even with a TTimer this will hang your program because Sleep(1000) and a TTCPBlockSocket will stop the complete "main thread" of your program.
Normally your program has one execution-path. Every command is executed after the other. Because of an elaborate messaging system and the complexity of the whole Lazarus framework you don't notice this all the time but even after your procedure or functions ends... in that framework, every instruction is after another.
Now comes in threads. Do you have knowledge of multi-core CPUs? If you have one CPU, it can only execute one instruction at a time. If you have 2, 4 or even 8 core CPU, that CPU can process multiple instructions at the same time (each instruction in its own core). Threads work kinda the same way. You can see it as a complete function/unit/class which is executed besides your program (at the same time). Or like executing two different programs simultaneously.
I've attached a small example for a thread (with comments).
The example shows that when you click the button, a thread is made which fills in the memo. Meanwhile you can keep on typing in your TEdit without interruption. You could also do this with a TTimer but the upside of a thread is that is really executed separately (unlike a TTimer). When you have long-running procedures or blocking procedures, you can use threads without problems and with a TTimer you end up in trouble.
The only problem with a thread is that you may not update the components of another thread (because it's executed separately). So in your thread you can't just update the Form1.Memo1. You need to call a special procedure Synchronize to execute a small procedure in the thread of Form1. Essentially thread2 forces a procedure to be executed by (the main) thread1 with Synchronize.
Look at the attached example and see if you understand the comments I placed in it.
(anybody else have a beginners guide to threads lying around ?)
Complete example is also attached.
// -----------------------------------------------------------
// this is thread code
// -----------------------------------------------------------
type
TMyTickerThread = class(TThread)
private
Ticker: integer;
procedure ShowTickerInMemo;
protected
procedure Execute; override;
public
constructor Create(CreateSuspended: boolean);
end;
constructor TMyTickerThread.Create(CreateSuspended: boolean);
begin
inherited Create(CreateSuspended);
FreeOnTerminate := True; // this will free the thread automatically
Ticker := 0;
end;
procedure TMyTickerThread.ShowTickerInMemo;
begin
// this procedure is defined in the sub-thread but executed in the main-thread
// that's why we can update Form1 components safely
Form1.Memo1.Lines.Add(IntToStr(Ticker));
end;
procedure TMyTickerThread.Execute;
begin
// this will run until ricker hits 20
while not Terminated and (Ticker < 20) do
begin
// wait half a second
// because we are in a thread it will not effect the TEdit of the main program thread
Sleep(500);
Inc(Ticker);
// because we are in a thread we can't just update the main-threads components
// we need to call ShowTickerInMemo "in" the main thread
// we do this with Synchronize
Synchronize(@ShowTickerInMemo);
end;
end;
// -----------------------------------------------------------
// -----------------------------------------------------------
procedure TForm1.btStartThreadClick(Sender: TObject);
var
MyThread: TMyTickerThread;
begin
// This creates the thread and executes it directly
MyThread := TMyTickerThread.Create(False { suspend = false so start directly });
// MyThread is automatically freed because we set FreeOnTerminate in the thread to true
end;
You can even click the button multiple times and multiple threads will be made and executed. Try it.
I'm not sure I made the best explanation but I did my best
