gpt4 book ai didi

c# - 达到 DateTime 后执行方法的最有效方法

转载 作者:行者123 更新时间:2023-12-04 00:31:40 30 4
gpt4 key购买 nike

我有一个类是这样的:

public sealed class Contract
{
public bool isExpired { get; set; }
public DateTime ExpirationDate { get; set; }
public void MarkAsExpired()
{
this.isExpired = true;
// Other stuff..
}
}

我想做的是:一旦到达 ExpirationDate,就应该调用 MarkAsExpired。如果程序关闭并且在它重新打开时,ExpirationDate 已经过去,同样应该发生。如果 isExpired 为真,则什么都不会发生。

合约是可以修改的,并且经常添加新合约。我的确切预期数量未知。

我已经想到了一种可以通过 DateTime 对象的通用扩展方法来完成的方法:

var contracts = new List<Contract>();
foreach (var contract in contracts.Where(contract => !contract.isExpired))
{
contract.ExpirationDate.ExecuteWhenPassed(() => contract.MarkAsExpired());
}

问题在于编写扩展方法本身。我已经创建了一个可行的解决方案:

static void ExecuteWhenPassed(this DateTime date, Action action)
{
// Check if date has already passed
if (date <= DateTime.Now)
{
action();
}
else
{
// Timer will fire when $date is reached
var timer = new Timer { Interval = date.Subtract(DateTime.Now).TotalMilliseconds, AutoReset = false };
timer.Elapsed += (s, e) => action();
timer.Start();
}
}

而且效果很好。但是,我担心它的效率。具体来说,我担心为每个 Contract 实例创建单独的计时器所涉及的开销,其中可能有数百个尚未过期。

开销很大吗?如果是这样,处理这个问题的更有效方法是什么?

只要我处理过期的问题得到解决,我就可以接受完全不同的方法。

最佳答案

我建议为此使用 Microsoft 的 Reactive Framework(NuGet“System.Reactive”)。它变得 super 简单。

代码如下:

List<Contract> contracts = new List<Contract>();

/* populate `contracts` here before `query` */

IObservable<Contract> query =
from i in Observable.Interval(TimeSpan.FromMinutes(1.0))
from c in contracts
where !c.isExpired
where c.ExpirationDate <= DateTime.Now
select c;

IDisposable subscription =
query
.Subscribe(c => c.MarkAsExpired());

这是在设置一个每分钟触发一个值的可观察计时器 (Observable.Interval(TimeSpan.FromMinutes(1.0)))。然后,每隔一分钟,它都会将契约(Contract)列表过滤为那些尚未到期以及到期数据早于现在的契约(Contract)。

然后在 subscription 中,它只获取这些值的流并将它们标记为已过期。

如果您想停止处理,只需调用 subscription.Dispose()。这是一段非常简单的代码。

如果您在 Windows 窗体上运行此代码,您可以执行 .ObserveOn(instanceOfFormOrControl) 以编码回 UI 线程。在 WPF 上它是 .ObserveOnDispatcher()。该代码就在 .Subscribe(...) 之前。

关于c# - 达到 DateTime 后执行方法的最有效方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44879421/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com