Working with Threads

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(0100) > 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:

Developing User Application