The main code, which sets logic of application work and implements various algorithms, is written in procedures or functions. When procedures or functions are started, their code is executed consequently; if a long action is made in the code, the application waits its completion, form controls are unavailable. To be able to continue working with the application, long operations are started in separate threads. Threads enable the user to execute operations in parallel to the main application code; the application can be used to monitor and control thread state.
In the Fore language threads are implemented by the ForeThread class. A thread is based on a custom method implemented by the ForeMethod class. A custom method must be linked to the procedure or function that is in the assembly's global namespace:
Sub StartThread;
Var
Method: IForeMethod;
Th: IForeThread;
Begin
Method := New ForeMethod.Create;
Method.Assembly := "M_Thread";
Method.Method := "Calculate";
Th := New ForeThread.Create(Method);
Th.Start(Th);
End Sub StartThread;
Sub Calculate(Param: Variant);
Var
Th: IForeThread;
i: Integer;
Begin
Th := Param As IForeThread;
For i := 1 To 100 Do
//...
Debug.WriteLine("Working thread..." + i.ToString);
Th.Sleep(100);
//...
End For;
End Sub Calculate;
Working with threads can be executed via global variables, static fields or class properties. To avoid conflicts when different threads try to change value of the same common resource at the same time, critical sections are used. A critical section is implemented by the ForeCriticalSection class. Access to common resources must be executed between calling the Enter and Leave methods:
Var Value: Integer;
Class CCritSection: Object
Shared fcs: IForeCriticalSection;
Public Shared Property CritSection: IForeCriticalSection
Get
Begin
If IsNull(fcs) Then
fcs := New ForeCriticalSection.Create;
End If;
Return fcs;
End Get
End Property CritSection;
End Class CCritSection;
Sub StartThread;
Var
Method: IForeMethod;
Th1, Th2: IForeThread;
Begin
Method := New ForeMethod.Create;
Method.Assembly := "M_Thread";
Method.Method := "Calculate";
//Create threads
Th1 := New ForeThread.Create(Method);
Th1.Name := "A";
Th1.Start(Th1);
Th2 := New ForeThread.Create(Method);
Th2.Name := "B";
Th2.Start(Th2);
End Sub StartThread;
Sub Calculate(Th: Variant);
Var
i: Integer;
Begin
//Enter critical section
CCritSection.CritSection.Enter;
For i := 0 To 100 Do
If Math.RandBetweenI(0, 100) > 50 Then
Value := Value + 1
Else
Value := Value - 1
End If;
End For;
ThName := (Th As IForeThread).Name;
//Leave critical section
CCritSection.CritSection.Leave;
End Sub Calculate;
See also: