【问题标题】:Performing wait operation in ASP.NET web application?在 ASP.NET Web 应用程序中执行等待操作?
【发布时间】:2012-02-24 01:11:03
【问题描述】:

我想附上this 的问题,但也许换个角度。

出于反欺诈目的,我想在一定次数的错误登录尝试后阻止访问者。此时我有一个管理器类,它包装了登录的实际函数调用。如果访问者被阻止,则管理器会抛出异常,因此永远不会调用实际的登录方法。到目前为止一切顺利。

我现在想将异常抛出部分更改为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();
    }
}

【问题讨论】:

  • 为什么不简单地将块的持续时间存储在存储用户凭据的同一数据库中?

标签: asp.net performance sleep async-await


【解决方案1】:

您可以创建一个仅延迟一段时间的任务(已经可以使用的辅助方法 - 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");

【讨论】:

  • 我知道这不会“捆绑”一个线程。但这可能会导致服务器上出现大量“等待”线程吗?
  • 一个 ASP.NET 线程不等待 - 它是等待的请求。 ASP.NET 线程立即返回到线程池。当延迟结束时,从线程池中取出一个 ASP.NET 线程并用于继续(并可能完成)请求。
【解决方案2】:

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

【讨论】:

  • 这是最初的解决方案。但是,这确实需要用户向服务器发送另一个请求以登录。该代码实际上不是用于登录场景,而是用于在循环中执行的其他内容。登录场景更容易解释。但是,如果这个wait 操作也会消耗资源(我想在这里找到一些东西,是的,会有很多访问者),那么这是不行的,当前的解决方案将保持不变。跨度>
  • 这取决于你等待的时间,但是这个等待操作几乎肯定会比仅仅处理一个新的请求消耗更多的资源。想想看,每个请求都有一定的开销(特别是如果你做一些复杂的事情),那就是在阻塞期过去之前你无法释放的内存。再加上用户知道发生了什么的好处(您甚至可以使用 javascript 自动发送新请求)并且您会同意在服务器上等待不是要走的路。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-19
相关资源
最近更新 更多