【问题标题】:Is there any delayed MultiCast-Event, which is able to be interruptable?是否有任何延迟的 MultiCast-Event,它可以被中断?
【发布时间】:2019-07-16 15:05:08
【问题描述】:

我正在寻找一个可中断的延迟事件,我希望它已经成为 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 中解决这个任务的东西。

罗洛

【问题讨论】:

  • 这里描述的“IdleWorker”是什么意思delphipraxis.net/1305417-post11.html 我想以类似的方式开始一个事件,但能够在它真正触发之前中断它。在 S4D 中是否为此类用例做好了准备?

标签: spring4d


【解决方案1】:

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

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

以 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&lt;T&gt;.Invoke 不是一个方法,而是一个返回 T 的属性,您可以调用它(这使它看起来像一个方法调用自己)。

正如我所说,除此之外的任何事情都需要保留传递给 Invoke 的参数以便稍后传递它们(在某种程度上,匿名方法对你来说是这样的),这不是微不足道的(至少在我们谈论通用 @987654324 时不是这样) @)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-07-20
    • 2016-11-10
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 1970-01-01
    • 1970-01-01
    • 2020-11-14
    相关资源
    最近更新 更多