delphi tcollection

In this article event objects are discussed. As well as mutexs events are Win32 kernel objects and can be used for in- and inter-process thread synchronization. All kernel object attributes are also applied to events. So events can have a name, are accessed by handle, etc. For more information see previous articles.

Why to use events.

Sometimes, you need to wait for a thread to finish some operation rather than waiting for a particular thread to complete execution. To do this, use an event object. Global event objects can act like signals that are visible to all threads. There are two types of events: auto-reset events and manual-reset events. Event objects are also used in overlapped operations on disk files or other slow devices.

Auto-reset events

.Such type of events is also called autoclearing event or synchronization event. When such event is set to signaled state, a single thread that is waiting on the event becomes eligible for execution and the event’s state is automatically reset to non-signaled.

Manual-reset events.

Such type of events is also called notification event. When such event is set to signaled state, all threads that are waiting on the event becomes eligible for execution and the event’s state is not changed until any thread explicitly reset the signal.

Working with events.

Before executing new thread you should create new named or unnamed event object and obtain its handle using CreateEvent API function. You should pass following parameters:

  • lpSecurityAttriputes – pointer to structure that specifies the security attributes. You should simple pass nil value.
  • bManualReset:Boolean – Specifies whether a manual-reset or auto reset event object is created.
  • lpName:PChar – points to string specifying the name for the event object. If it is Nil unnamed event object is created.
  • bInitialState – Specifies the initial state of the event object. If TRUE, the initial state is signaled; otherwise, it is nonsignaled.

If the function succeed, the return value is a handle of the event object.

Certainly, this handle should be closed later by calling CloseHandle.

The thread that waits for the task completion should call WaitForSingleObject (or other WaitForXXX) function passing the event object handle as hObject parameter. The WaitForSingleObject function does not return until the state of the event object is set to signaled or timeout interval elapsed.

After the task is completed the thread should set the state of the event object to signaled by calling SetEvent. The state of a manual-reset event object remains signaled until it is explicitly set to non-signaled state by the ResetEvent function. The state of a manual-reset event object remains signaled until a single waiting thread is released. After that the system automatically sets the state to non-signaled. If no threads are waiting, the event object’s state remains signaled.

Source code.

Uses Windows.
Interface

TILEvent = class
Private

    FHandle: THandle;

public

    constructor Create(EventAttributes: PSecurityAttributes; 
ManualReset,InitialState: Boolean; const Name: string);
    function WaitFor(Timeout: Longint): boolean;
    procedure SetEvent;
    procedure ResetEvent;
    property Handle:THandle read Fhandle;

end;

implementation

{ TILEvent }
destructor TILEvent.Destroy;
begin

    CloseHandle(FHandle);

end;

constructor TILEvent.Create(EventAttributes: PSecurityAttributes; 
ManualReset, InitialState: Boolean; const Name: string);
begin

    FHandle := CreateEvent(EventAttributes, ManualReset, 
InitialState, PChar(Name));

end;

function TILEvent.WaitFor(Timeout: Longint):boolean;
begin

    result:= WaitForSingleObject(FHandle, Timeout) = WAIT_OBJECT_0;

end;

procedure TILEvent.SetEvent;
begin

    Windows.SetEvent(FHandle);

end;

procedure TILEvent.ResetEvent;
begin

    Windows.ResetEvent(FHandle);

end;

 

Leave a Reply

Your email address will not be published.