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;
}
}
}