Есть ли задержанное MultiCast-событие, которое может быть прерываемым? - PullRequest
0 голосов
/ 22 февраля 2019

Я ищу прерывистое, отложенное событие, которое, я надеюсь, уже может быть частью Spring4D или легко реализовано там.

Как лучше всего в любом случае добиться этого?

Вероятно, Событие не будет правильным местом.

По сути, ищем что-то вроде

Event.InvokeDelayed (1000, nil); и Событие.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;

Возможно, я наблюдаю за тем, что уже доступно для решения этой задачи в S4D.

Rollo

1 Ответ

0 голосов
/ 19 марта 2019

Нет, многоадресные события, как они есть в библиотеке, являются синхронными.Для того, чтобы они работали должным образом асинхронно во всех случаях, это потребовало бы не просто задержки их вызова, но и захвата любых данных, которые вы передаете через них, убедитесь, что данные не становятся недействительными и т. Д.

Если вам нуженМеханизм, подобный этому, вы должны использовать одну из существующих библиотек для асинхронных операций.

Например, с PPL (простой код, чтобы просто показать концепцию):

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;

Вы можетевероятно, оберните это в свою собственную рутину в зависимости от ваших потребностей и фактической реализации.Однако невозможно создать метод InvokeDelayed с дополнительным параметром, который имеет тип события в качестве сигнатуры, поскольку Event<T>.Invoke - это не метод, а свойство, возвращающее T, которое вы можете вызвать (что делает его похожим на метод).вызовите себя).

Все, что помимо этого требует, как я уже говорил, сохранения параметров, переданных Invoke, для их последующей передачи (что-то, что анонимные методы для вас в определенной степени), что не является тривиальным (по крайней мере, когда мыговорят о родовом Event<T>)

...