0

I am looking for an interruptable, delayed event, which I hope could be already part of Spring4D, or easily implemented there.

What would be best way anyway, to achieve this ?

Probably the Event wouldn't be the right place.

Basically looking for something like

Event.InvokeDelayed(1000, nil); and Event.InvokeCancel;

    procedure TTestMulticastEvent.Test;
    var
      e: Event<TNotifyEvent>;
    begin
      e.Add(HandlerA);
      e.Invoke(nil); // Yes, this is the normal behaviour

      // But would this make sense in Events,
      // or better use other concept, like TTask.IdleWorker, e.g. ?
      e.InvokeDelayed(1000, nil); // waits 1sec
      Sleep(100);  // Interrupts after 100ms
      e.InvokeCancel; // Prevent future Event, started earlier

    end;

Maybe I oversee something already available to solve this task in S4D.

Rollo

Rollo62
  • 1
  • 1
  • What I mean with "IdleWorker" ist described here https://www.delphipraxis.net/1305417-post11.html I would like to start an event in a similar way, but be able to interrupt this before it really triggers. Is there anything ready prepared for such use case in S4D ? – Rollo62 Feb 28 '19 at 07:47

1 Answers1

0

No, multicast events as they are in the library are synchronous. For them to work properly asynchronously in all cases it would require way more than just delaying their invokation but capturing any data you pass through them, make sure that data does not get invalid and so on.

If you need a mechanism like that you should use one of the existing libraries out there to do asynchronous things.

For example with the PPL (naive code to just show the concept):

var
  e: Event<TNotifyEvent>;
  t: ITask;
begin
  e.Add(HandlerA);

  t := TTask.Run(
    procedure
    begin
      Sleep(1000);
      if t.Status <> TTaskStatus.Canceled then
        TThread.Synchronize(nil,
          procedure
          begin
            e.Invoke(nil);
          end);
    end);

  Sleep(100);
  t.Cancel;
end;

You can probably wrap this into your own routine depending on your needs and the actual implementation. It will not be possible however to make a InvokeDelayed method with an additional parameter to what the event type has as signature because Event<T>.Invoke is not a method but a property returning T which you can invoke (which makes it look like a method call itself).

Anything beyond that requires as I said preserving the parameters passed to Invoke to pass them later (something that anonymous methods to for you to a certain degree) which is not trivial (at least not when we are talking about the generic Event<T>)

Stefan Glienke
  • 20,860
  • 2
  • 48
  • 102