C# 异步编程#

C# 异步编程#,c#,email,asynchronous,async-await,C#,Email,Asynchronous,Async Await,我正在建立一个注册屏幕。用户提交其详细信息后,会向其电子邮件Id发送一封电子邮件,为其提供激活链接。使用jquery Ajax(异步POST请求)将用户的注册详细信息提交到服务器(ASP.MVC控制器操作) 首先将这些详细信息保存到数据库中,然后通过调用SendEmail方法向用户发送电子邮件 我已将此SendEmail方法创建为异步方法。以下是我如何实施它的: public async static Task SendEmail(Dictionary<string, object>

我正在建立一个注册屏幕。用户提交其详细信息后,会向其电子邮件Id发送一封电子邮件,为其提供激活链接。使用jquery Ajax(异步POST请求)将用户的注册详细信息提交到服务器(ASP.MVC控制器操作)

首先将这些详细信息保存到数据库中,然后通过调用SendEmail方法向用户发送电子邮件

我已将此SendEmail方法创建为异步方法。以下是我如何实施它的:

public async static Task SendEmail(Dictionary<string, object> parameters, string connectionString)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                SqlCommand sqlComm = conn.CreateCommand();
                sqlComm.CommandType = System.Data.CommandType.StoredProcedure;
                sqlComm.CommandText = "emailSendingProc";

                foreach (var param in parameters)
                {
                    if (param.Value == null)
                    {
                        sqlComm.Parameters.AddWithValue("@" + param.Key, DBNull.Value);
                    }
                    else
                    {
                        sqlComm.Parameters.AddWithValue("@" + param.Key, param.Value);
                    }
                }

                await SendEmail(conn, sqlComm);
            }
        }

private async static Task SendEmail(SqlConnection conn, SqlCommand sqlComm)
        {
            try
            {
                await conn.OpenAsync();
                await sqlComm.ExecuteNonQueryAsync();
            }
            catch (Exception ex)
            {
               //Log Exception
            }
            finally
            {
                conn.Close();
            }
        }
公共异步静态任务SendEmail(字典参数、字符串连接字符串)
{
使用(SqlConnection conn=newsqlconnection(connectionString))
{
SqlCommand sqlComm=conn.CreateCommand();
sqlComm.CommandType=System.Data.CommandType.StoredProcess;
sqlComm.CommandText=“emailSendingProc”;
foreach(参数中的var参数)
{
if(param.Value==null)
{
sqlComm.Parameters.AddWithValue(“@”+param.Key,DBNull.Value);
}
其他的
{
sqlComm.Parameters.AddWithValue(“@”+参数键,参数值);
}
}
等待发送电子邮件(conn、sqlComm);
}
}
专用异步静态任务SendEmail(SqlConnection conn、SqlCommand sqlComm)
{
尝试
{
等待连接OpenAsync();
等待sqlComm.ExecuteNonQueryAsync();
}
捕获(例外情况除外)
{
//日志异常
}
最后
{
康涅狄格州关闭();
}
}
仅供参考:电子邮件是使用存储过程“emailSendingProc”从数据库发送的。发送电子邮件的数据库与保存注册详细信息的数据库不同

如果在电子邮件发送中出现任何故障(连接超时、数据库服务器未响应等),我不希望用户体验到这一点,因此我接受异常,但记录它

使用异步方法满足此要求是否合理

编辑:

作为一个POC,我使用了普通方法和异步方法,并在db连接失败的情况下检查了浏览器请求的响应时间。我本可以上传比较图片,但没有这样做的声誉:(

我观察到使用异步方法时的响应时间比普通方法少得多。下面是普通方法的实现:

public static void SendEmail(Dictionary<string, object> parameters, string connectionString)
        {
            using (SqlConnection conn = new SqlConnection(connectionString))
            {
                SqlCommand sqlComm = conn.CreateCommand();
                sqlComm.CommandType = System.Data.CommandType.StoredProcedure;
                sqlComm.CommandText = "emailSendingProc";

                foreach (var param in parameters)
                {
                    if (param.Value == null)
                    {
                        sqlComm.Parameters.AddWithValue("@" + param.Key, DBNull.Value);
                    }
                    else
                    {
                        sqlComm.Parameters.AddWithValue("@" + param.Key, param.Value);
                    }
                }

                SendEmail(conn, sqlComm);
            }
        }

        private static void SendEmail(SqlConnection conn, SqlCommand sqlComm)
        {
            try
            {
                conn.Open();
                sqlComm.ExecuteNonQuery();
            }
            catch (Exception ex)
            {
                var mess = ex.Message;
            }
            finally
            {
                conn.Close();
            }
        }
publicstaticvoidsendmail(字典参数、字符串连接字符串)
{
使用(SqlConnection conn=newsqlconnection(connectionString))
{
SqlCommand sqlComm=conn.CreateCommand();
sqlComm.CommandType=System.Data.CommandType.StoredProcess;
sqlComm.CommandText=“emailSendingProc”;
foreach(参数中的var参数)
{
if(param.Value==null)
{
sqlComm.Parameters.AddWithValue(“@”+param.Key,DBNull.Value);
}
其他的
{
sqlComm.Parameters.AddWithValue(“@”+参数键,参数值);
}
}
发送电子邮件(conn、sqlComm);
}
}
专用静态void sendmail(SqlConnection conn、SqlCommand sqlComm)
{
尝试
{
conn.Open();
sqlComm.ExecuteNonQuery();
}
捕获(例外情况除外)
{
var mess=ex.消息;
}
最后
{
康涅狄格州关闭();
}
}

有没有想过为什么使用异步方法会更快?

是的,这是使用异步的一个有效方案。通过使用异步模式,您可以释放工作线程,以便在等待数据库响应时处理更多传入请求,从而增加负载下的可能吞吐量。

这不会返回到browser更快,以这种方式使用异步允许重复使用线程,并在IO完成时完成等待。所以这很好

看看这个博客,不是我的,而是一个很棒的名字:)


如果您不希望用户等待电子邮件操作,那么您应该考虑排队并处理队列。(我假设SQL调用可能会发送电子邮件)

async与隐藏异常无关,但这将隐藏异常实际上我隐藏异常的原因是系统需要很长时间才能确定存在连接故障。在此期间,我不希望我的应用程序没有响应。因此,我将sendEmail声明为异步方法。@Aashish:
async
不会返回浏览器。在
wait
完成并返回响应之前,请求不会完成。是的,看起来是这样。你会建议一个解决方法吗?不要尝试使用任务。运行时不等待发送电子邮件。顺便说一句:)是的,排队似乎是最后的选择:)将任务。尽快运行返回浏览器控制?我认为排队可能是一个有效的选项,你可以始终使用SQL代理每隔几分钟触发发送。这就是像CRM这样的系统如何做到的。您不希望您的代码仅在电子邮件服务器启动等情况下工作。如果您不等待,则会收到编译器警告,它只会运行您的代码,而不会等待。但这是一个糟糕的模式。它会转动一根线。。这将是一个糟糕的模式:)