在不等待答案的情况下调用方法异步

时间:2014-12-24 14:11:22

标签: c# .net asp.net-mvc asynchronous async-await

我有MVC应用程序,我想保留有关我网站活动的活动日志,例如, 如果用户登录成功,则向我的数据库插入描述此活动的行(用户名为X登录时间为Y,ip为Z.

问题是我需要等待结果,我不关心结果,我不希望结果阻止我,我想将它发送给函数(更新Activity表中的数据库功能)并继续。

我会自下而上开始:

这是我的数据查询功能:

public static void InsertLogRecord(LogRecord lg)
{
    try
    {
         string query = "INSERT INTO ActivityLog VALUES('" + lg.Id + "','" + lg.Time + "','" + lg.Executor + "','" + lg.ExecutedOn + "','" + lg.Action + "','" + lg.StartState + "','" + lg.EndState + "','" + lg.IP + "')";

         AdoHelper.ExecuteNonQuery(query);
    }

    catch(Exception ex)
    {
         throw ex;
    }

}

这是我的Controller函数(调用前面的“InsertLogRecord”函数)

public void UpdateLog(string exeOn, string action, string sState, string eState)
{
     LogRecord lg = new LogRecord(Guid.NewGuid().ToString(), DateTime.Now, User.Identity.Name, exeOn, action, sState, eState, Request.ServerVariables["REMOTE_ADDR"]);

     DataQueries.InsertLogRecord(lg);
}

使用示例:(在日志中存储操作记录,“用户登录”)

public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)
{
    if (!ModelState.IsValid)
    {
        return View(model);
    }

    var result = await SignInManager.PasswordSignInAsync(model.UserName, model.Password, model.RememberMe, shouldLockout: false);

    switch (result)
    {
        case SignInStatus.Success:

              // Just before redirecting the user to the site I want to store the info' on my DB

             UpdateLog("", "Log in", "", "");

            return RedirectToLocal(returnUrl);


        case SignInStatus.LockedOut:
            return View("Lockout");
    }
}

我该怎么做呢?

2 个答案:

答案 0 :(得分:9)

您需要的是一种可靠的方法,可以将项目排入&#34; Fire and Forget&#34; FASION。你可以做的是使用.NET 4.5.2中引入的HostingEnvironment.QueueBackgroundWorkItem,它排队工作并通知ASP.NET环境,这样当它试图回收你的应用程序时,它就会知道待处理的工作仍在发挥作用。 / p>

如果您使用的是以前版本的.NET框架,则可以使用Stephan Clearys BackgroundTaskManager

我还建议在Fire and Forget in ASP.NET

上阅读stephans帖子

修改

为了使用HostingEnvironment对工作进行排队,只需将其传递给委托即可。它可以是Action<CancellationToken>Func<CancellationToken, Task>

以下是使用Lambda Expression的示例:

HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
{
   // Put code here.
});

答案 1 :(得分:0)

您是否尝试过使用ExecuteNonQuery的异步版本?

http://msdn.microsoft.com/en-us/library/hh223678(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1

AdoHelper.ExecuteNonQueryAsync(query);