Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 登录后的异步记录器_C#_.net_Asp.net Mvc_Asynchronous - Fatal编程技术网

C# 登录后的异步记录器

C# 登录后的异步记录器,c#,.net,asp.net-mvc,asynchronous,C#,.net,Asp.net Mvc,Asynchronous,我有Loginpost操作: [HttpPost] public ActionResult Login(LoginModel model, string post) { Repo.Resolve<ILogsRepository>().LogLoginAttempt(model.Username, this.Request.UserHostAddress, this.Request.RawUrl); if (ModelState

我有
Login
post操作:

    [HttpPost]
    public ActionResult Login(LoginModel model, string post)
    {
        Repo.Resolve<ILogsRepository>().LogLoginAttempt(model.Username, this.Request.UserHostAddress, this.Request.RawUrl);

        if (ModelState.IsValid) {
            var login = this._authRepository.ValidateCredentials(model.Username, model.Password);
            if (login != null) {
                Logger.LogAsync(Action.UserSignIn, Level.Log, string.Format("User signed in as '{0}' -> '{1}'", model.Username, login));

                return Request.IsAjaxRequest() ? Content("__close__") : ClientCabinet();
            }

            Logger.LogAsync(Action.UserSignIn, Level.Mandatory, Event.Error, string.Format("User failed to sign in as '{0}': invalid username or password", model.Username));

            ModelState.AddModelError("Username", @"login or password is incorrect!");
        }

        return View(model);
    }
因此,我想在
validateRedentials
返回正确结果后,实现
Logger
的异步操作

但是,如果我在
LogAsync
Thread.Sleep
中添加断点,则方法会阻塞并仍然同步处理


登录验证后,如何实现方法的异步执行?

我想您对
wait
将做什么感到困惑。
await
操作符应用于异步方法中的
任务
,以暂停该方法的执行,直到等待的任务完成
任务
表示正在进行的工作

在您的情况下,看起来您更愿意通过使用一个新的线程句柄来“启动并忘记”,然后继续使用当前的方法(这不是我推荐的方法,因为除非您等待任务完成并处理该异常,否则您不会知道是否出了问题,但如果您不在意,则可以)

如果是这样,那么只需启动一个任务,它将具有您正在寻找的异步行为:

Task.Run(() => Log(action, level, message));
因此,在您的代码中,它将如下所示:

[HttpPost]
public ActionResult Login(LoginModel model, string post)
{
    Repo.Resolve<ILogsRepository>().LogLoginAttempt(model.Username, this.Request.UserHostAddress, this.Request.RawUrl);

    if (ModelState.IsValid) {
        var login = this._authRepository.ValidateCredentials(model.Username, model.Password);
        if (login != null) {
            Task.Run(() => Logger.Log(Action.UserSignIn, Level.Log, string.Format("User signed in as '{0}' -> '{1}'", model.Username, login)));

            return Request.IsAjaxRequest() ? Content("__close__") : ClientCabinet();
        }

       Task.Run(() => Logger.Log(Action.UserSignIn, Level.Mandatory, Event.Error, string.Format("User failed to sign in as '{0}': invalid username or password", model.Username)));

        ModelState.AddModelError("Username", @"login or password is incorrect!");
    }

    return View(model);
}

看起来您希望尽快向用户返回响应,然后“将来某个时候”登录用户登录。下面的帖子对此或类似问题给出了回答:

至少对我来说,这篇文章的要点是。只有在不在乎方法是否失败的情况下,才应使用Fire-And-Forget方法。在这种情况下,如果记录有关用户登录的信息对您很重要,那么您不应该走这条路


也许这取决于日志记录操作需要多长时间,以及您可以接受多长时间。这种事情的一种策略是使用消息队列。也就是说,您将需要登录的信息发布到消息队列中,其他一些进程(可能在另一台机器上)从队列中读取消息并进行实际的日志记录。虽然我看不出这比一开始就记录信息要快得多。

是的,看起来我对
async/await
Task.Run
的区别有点混乱。泰。
[HttpPost]
public ActionResult Login(LoginModel model, string post)
{
    Repo.Resolve<ILogsRepository>().LogLoginAttempt(model.Username, this.Request.UserHostAddress, this.Request.RawUrl);

    if (ModelState.IsValid) {
        var login = this._authRepository.ValidateCredentials(model.Username, model.Password);
        if (login != null) {
            Task.Run(() => Logger.Log(Action.UserSignIn, Level.Log, string.Format("User signed in as '{0}' -> '{1}'", model.Username, login)));

            return Request.IsAjaxRequest() ? Content("__close__") : ClientCabinet();
        }

       Task.Run(() => Logger.Log(Action.UserSignIn, Level.Mandatory, Event.Error, string.Format("User failed to sign in as '{0}': invalid username or password", model.Username)));

        ModelState.AddModelError("Username", @"login or password is incorrect!");
    }

    return View(model);
}
task1 = Task.Run(() => Log(arg1, arg2, arg3));

try
{
    task1.Wait();
}
catch (AggregateException ae)
{
    // Assume we know what's going on with this particular exception. 
    // Rethrow anything else. AggregateException.Handle provides 

    foreach (var e in ae.InnerExceptions)
    {
        if (e is MyCustomException)
        {
            Console.WriteLine(e.Message);
        }
        else
        {
            throw;
        }
    }

}