.NET Core替代ThreadPool.QueueUserWorkItem

时间:2016-02-03 11:35:45

标签: asp.net-core .net-core

我正在努力实现ForgotPassword功能,即在标准VS 2015项目模板中使用ASP.NET Identity的AccountController中。

我试图解决的问题是,当发送密码重置电子邮件时,页面响应会有明显的延迟。如果密码恢复尝试未找到现有帐户,则不会发送任何电子邮件,因此响应速度更快。所以我认为这个明显的延迟可以用于帐户枚举,也就是说,黑客可以根据忘记密码页面的响应时间来确定帐户是否存在。

所以我想消除页面响应时间的这种差异,以便无法检测是否找到了帐户。

在过去,我排队了可能很慢的任务,例如使用以下代码将电子邮件发送到后台线程:

ThreadPool.QueueUserWorkItem(new WaitCallback(AccountNotification.SendPasswordResetLink), 
notificationInfo);

但.NET Core中不存在ThreadPool.QueueUserWorkItem,因此我需要一些替代方案。

我想一个想法是在没有找到Thread.Sleep帐户的情况下引入人为延迟,但我宁愿找到一种方法来发送电子邮件而不会阻止UI。

更新:为了澄清我发布实际代码的问题:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<IActionResult> ForgotPassword(ForgotPasswordViewModel model)
{   
    if (ModelState.IsValid)
    {
    var user = await userManager.FindByNameAsync(model.Email);
    if (user == null || !(await userManager.IsEmailConfirmedAsync(user)))
    {
        // Don't reveal that the user does not exist or is not confirmed
        return View("ForgotPasswordConfirmation");
    }

    var code = await userManager.GeneratePasswordResetTokenAsync(user);
    var resetUrl = Url.Action("ResetPassword", "Account", 
        new { userId = user.Id, code = code }, 
        protocol: HttpContext.Request.Scheme);

    //there is a noticeable delay in the UI here because we are awaiting
    await emailSender.SendPasswordResetEmailAsync(
    userManager.Site,
    model.Email,
    "Reset Password",
    resetUrl);


        return View("ForgotPasswordConfirmation");
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

是否有一种使用其他内置框架功能来处理此问题的好方法?

1 个答案:

答案 0 :(得分:3)

只是不要等待任务。那么这大部分等同于在线程池上运行所有代码开始,假设它没有在内部等待任何事情而不调用ConfigureAwait(false)。 (如果是您的代码,您需要检查一下。)

可能希望将任务添加到服务器关闭之前应该等待的一组任务中,假设在ASP.NET中有一些适当的“请求关闭”概念。这是值得研究的,并且会在发送响应之后但在发送通知之前由于服务器立即关闭的不幸时间而停止通知丢失。在发送通知存在问题的情况下,不会帮助,例如,您的邮件服务器已关闭。此时,用户被告知电子邮件正在发送,之后您才能真正保证......只需要考虑一下。