C# 构建自维护集合以在项目过期时删除它们?

C# 构建自维护集合以在项目过期时删除它们?,c#,asp.net-mvc,design-patterns,collections,concurrency,C#,Asp.net Mvc,Design Patterns,Collections,Concurrency,我正在构建一个系统,允许用户输入一个电话号码以添加到他们的帐户中。系统允许用户输入号码,然后将该号码添加到myPendingNumberManager,并设置过期时间。然后,我们向该号码发送一条文本消息,并等待用户在我们的应用程序中输入他们的验证码。如果他们为自己的帐户和号码输入了正确的验证码,则该号码将从PendingNumberManager中删除,并添加到他们的用户帐户中(并保留到数据库中) 总的来说,在我开始考虑自动到期之前,该功能相对简单。我立即想到的一些选项有: 除非有人试图获取过

我正在构建一个系统,允许用户输入一个电话号码以添加到他们的帐户中。系统允许用户输入号码,然后将该号码添加到my
PendingNumberManager
,并设置过期时间。然后,我们向该号码发送一条文本消息,并等待用户在我们的应用程序中输入他们的验证码。如果他们为自己的帐户和号码输入了正确的验证码,则该号码将从
PendingNumberManager
中删除,并添加到他们的用户帐户中(并保留到数据库中)

总的来说,在我开始考虑自动到期之前,该功能相对简单。我立即想到的一些选项有:

  • 除非有人试图获取过期条目,否则不要删除它们,然后删除单个过期条目。(随着时间的推移,可能会导致列表越来越满)
  • 在每次查找时检查过期条目。(每次查找都会导致额外的开销)
  • 在另一个线程中运行某种循环,只是定期检查过期的项目。(不需要时可能会消耗额外资源)
总的来说,我对如何以最有效的方式处理这个问题有些茫然。是否有任何设计模式或方法可以很好地解决这个问题


我们目前有一个
UserPhoneNumber
表,其中包含多个字段(包括
LastModified
Verified字段
)。在我们的系统中,我们有多个不同的数据源,可以将数据转储到
UserPhoneNumber
表中。该系统目前包含添加和验证电话号码的必要功能,通过各种数据源添加的号码可以在以后手动验证

在注册流程中,我们希望用户能够输入并验证给定的号码,而无需将该号码持久保存到
UserPhoneNumber
,除非先验证该号码。如果用户在验证其号码之前放弃了初始帐户设置/注册,他们将被迫在稍后再次通过该流程,因此我们无需保留基于注册的未验证号码。

这听起来像是“验证联系人数据”shema。但会话系统也遵循这一基本原则。你可以在网上看到这些

由于涉及相当长的实验时间,我肯定会在DB端解决这个问题,而不是在程序端。面对此问题,我的解决方案是让存储的produre taht使用两个作业的ID:

  • 删除所有时间段的内容
  • 请尝试检查此数字是否仍在表中
  • 如果成功了,我当然也会把它从桌面上删除


    这样,列表将快速自清除任何失败的尝试,并且您永远不会遇到数字保持有效的问题。考虑到该函数在每次注册时只被调用1到5次,这一小开销是可以接受的。这不是DB或程序的高流量区域。

    未经验证的电话号码是另一种实体。它有一些验证电话号码不需要的附加字段,例如验证码和验证码过期日期/时间。为了维护规范化的数据库设计,它将放在不同的表中,例如具有不同列的
    UserUnverifiedPhoneNumber

    对于需要验证电话号码的操作,应用程序仍将查询
    UserPhoneNumber
    表,该表不包括这些未验证的电话号码

    对于使用未验证电话号码的操作(例如,您的注册流程),应用程序将查询
    UserUnverifiedPhoneNumber
    表。当它这样做时,它会检查飞行中任何验证码的过期日期。如果该记录已过期,您可以选择:应用程序可以简单地假装该记录不存在,也可以为特殊情况提供一个UI(例如,“给我发送一个新的验证码”)


    最后一步是一个定期服务或SQL代理作业,它在
    UserUnverifiedPhoneNumber
    表中搜索过期超过X天的条目,并从物理上删除它们,这样表就不会继续增长。根据您的需要,您可以每小时、每天甚至每月运行此作业。

    为什么不让一个单独的服务每天(或每小时,或任何您喜欢的时间间隔)对数据库运行一次清理操作?我想这是你的第三个选择。但不确定它会“消耗”哪些资源
    DELETE FROM PendingNumbers WHERE ExpirationDate>GETDATE()
    @RufusL事实上,这些数字目前仅在30分钟内有效,因此我拥有这样一个短暂的表似乎很愚蠢。我没有理由不能实现清理作业,但是对于这样一个小的用例来说,开销似乎太大了。至于资源问题,我们的主平台已经遇到了一些我们一直在努力解决的内存不足问题,我们只是不想构建导致问题负载过大的东西。我假设您有一个
    PendingNumbers
    表,其中包含
    UserId
    PhoneNumber
    VerificationCode
    ExpirationDate
    。如果不是在表中,您将数字存储在哪里(如果您将它们存储在内存中,这可能是您遇到的问题的一部分)?你到底想清理什么?另外,在一个小表上运行这个服务器端会非常有效,不是吗?您指的是什么开销?如果您为每个条目分配租约是否有帮助?租约上有计时器。当此计时器过期时,您可以将其从内存队列中删除。否则,如果访问条目,您可以释放计时器并执行其他操作