我正在寻找一个可中断的,延迟的事件,我希望它可能已经是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中此任务的事情。
罗洛
答案 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}})