2012-02-23 36 views
1

我想钩入this的问题,但也许从不同的角度来重述它。在ASP.NET Web应用程序中执行等待操作?

为了反欺诈的目的,我想阻止访客在一定数量的错误登录尝试后。在这一点上,我有一个经理类,它包装实际的函数调用登录。如果访问者被阻止,管理器会抛出异常,因此实际的登录方法从不会被调用。到现在为止还挺好。

我现在想把异常抛出部分改成Thread.Sleep这种东西。但这不是一个选项,因为这会阻止对服务器的其他请求。是否有替代此场景可能使用一些async等待命令或可能使用F#

当前代码:

class Manager { 
    void Execute(Action action) { 
     if(user.IsBlocked) 
      throw new BlockedException(); 
     else 
      action(); 
    } 
} 

首选代码:

class Manager { 
    void Execute(Action action) { 
     if(user.IsBlocked) 
      //Wait for xxx minutes 


     action(); 
    } 
} 
+0

为什么不简单地将块的持续时间存储在存储用户凭证的相同数据库中? – 2012-02-23 14:53:33

回答

1

这样做,这样会很迅速地吃了资源。你不希望你的服务器上有多个线程(可能有几十个,取决于访问者的数量和你的块的持续时间),等待你最终发送你的响应。此外,访问者不清楚发生了什么;它看起来好像你的服务器没有响应(这是真的)。 更好的方法是继续抛出异常,并可能更优雅地处理异常。例如使用JavaScript在客户端显示倒计时,直到您再次尝试。

+0

这是最初的解决方案。但是,这确实要求用户发送另一个请求到服务器进行登录。代码实际上不是用于登录场景,而是用于循环中执行的其他内容。登录场景更容易解释。然而,如果这种“等待”操作也会吃掉资源(我试图在这里找到的东西,是的,会有大量的访问者),那么这是一个不行,目前的解决方案将保持原位。 – ReFocus 2012-02-23 15:10:15

+0

这取决于您等待的时间,但这种等待操作几乎肯定会比处理新请求消耗更多资源。想想看,每个请求都有一定的开销(特别是如果你做了一些复杂的事情),那就是内存,直到块周期结束,你才能释放它。除此之外,用户知道正在发生什么的好处(甚至可以使用JavaScript自动发送新的请求),并且您会同意在服务器上等待是不行的。 – EPLKleijntjens 2012-02-23 15:28:13

3

您可以创建一个只延迟一段时间的任务(已经有可用的帮助方法 - TaskEx.Delay)并等待 - 那么在此期间您不会绑定一个线程。

因此 “//等待XXX分钟” 将是 “等待TaskEx.Delay(TimeSpan.FromMinutes(XXX))”

这里你可以看到一个例子:

http://www.codeproject.com/Articles/127291/C-5-0-vNext-New-Asynchronous-Pattern

Console.WriteLine("Before await"); 
await TaskEx.Delay(1000); 
Console.WriteLine("After await"); 
+0

据我所知,这不会“捆绑”一个线程。但是这可能会在服务器上造成大量的“等待”线程吗? – ReFocus 2012-02-24 15:12:00

+1

ASP.NET线程不会等待 - 这是等待的请求。 ASP.NET线程立即返回到线程池。当延迟结束时,ASP.NET线程将从线程池中获取并用于继续(并可能完成)请求。 – 2012-02-24 20:27:11

相关问题