是否有任何可中断的延迟MultiCast事件?

时间:2019-02-22 13:44:15

标签: spring4d

我正在寻找一个可中断的,延迟的事件,我希望它可能已经是Spring4D的一部分,或者可以在那里轻松实现。

无论如何,实现这一目标的最佳方法是什么?

该活动可能不是合适的地点。

基本上在寻找类似的东西

Event.InvokeDelayed(1000,nil); 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;

也许我监督了一些可用于解决S4D中此任务的事情。

罗洛

1 个答案:

答案 0 :(得分:0)

否,库中的多播事件是同步的。为了使它们在所有情况下都能异步正常工作,它不仅需要延迟其调用,还需要捕获您通过它们传递的所有数据,并确保数据不会变得无效等等。

如果您需要类似的机制,则应该使用现有的库之一来执行异步操作。

例如,使用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的参数,以便稍后再传递(某种程度上为您使用匿名方法)(这在琐碎的情况下(至少在我们谈论泛型{{ 1}})