Asp.net Async ActionMethod-是否正确

Asp.net Async ActionMethod-是否正确,asp.net,asp.net-mvc-4,Asp.net,Asp.net Mvc 4,仅仅因为某些东西有效并不意味着它是正确的。因此,我想就以下代码获得一些反馈 一点历史;我试图发送/排队电子邮件时,一个用户在我们的网站上注册,遇到了一个线程被阻止的问题,这完全有道理,因为默认情况下控制器和关联的操作方法是同步而非异步的。为了解决这个问题,我总结了以下内容,但不确定这是否是最好的方法 [HttpPost, AllowAnonymous] public async Task<ActionResult> RegisterAsync(UserRegisterUse

仅仅因为某些东西有效并不意味着它是正确的。因此,我想就以下代码获得一些反馈

一点历史;我试图发送/排队电子邮件时,一个用户在我们的网站上注册,遇到了一个线程被阻止的问题,这完全有道理,因为默认情况下控制器和关联的操作方法是同步而非异步的。为了解决这个问题,我总结了以下内容,但不确定这是否是最好的方法

 [HttpPost, AllowAnonymous]
    public async Task<ActionResult> RegisterAsync(UserRegisterUserViewModel userRegisterUserViewModel)
    {
        if (ModelState.IsValid)
        {
            var user = new UserDto
                {
                    UserName = userRegisterUserViewModel.UserName,
                    Password = userRegisterUserViewModel.Password,
                    AuthType = userRegisterUserViewModel.AuthType,
                    Active = 0
                };
            Guid userId = _userService.AddUser(user);
            if (userId != Guid.Empty)
            {
                // Send Registration E-mail
                await Task.Run(() => _userMailer.RegistrationConfirmation(user).SendAsync(),
                               new CancellationToken(false));
                // Display Confirm View
                return PartialView("_RegistrationConfirmation");
            }
            ModelState.AddModelError("UserName", "Unable to create account");
        }
        return PartialView("_Registration");
    }
[HttpPost,AllowAnonymous]
公共异步任务注册表同步(UserRegisterUserServiewModel UserRegisterUserServiewModel)
{
if(ModelState.IsValid)
{
var user=new UserDto
{
UserName=userRegisterUserServiceWModel.UserName,
Password=userRegisterUserServiewModel.Password,
AuthType=UserRegisterUserServiewModel.AuthType,
活动=0
};
Guid userId=\u userService.AddUser(用户);
if(userId!=Guid.Empty)
{
//发送注册电子邮件
等待任务。运行(()=>_userMailer.RegistrationConfirmation(user.SendAsync(),
新的CancellationToken(false));
//显示确认视图
返回部分视图(“注册确认”);
}
AddModelError(“用户名”,“无法创建帐户”);
}
返回部分视图(“U注册”);
}
我不确定ASP.NET线程被阻塞会导致什么样的“问题”,但关于您的
异步
/
等待
代码:

  • new CancellationToken(false)
    没有意义,这与
    CancellationToken相同。None
    ,这与不提供
    CancellationToken
    参数相同
  • 可能没有指向
    Task.Run
    ,它在线程池线程上执行
    SendAsync
    。如果
    SendAsync
    是一种合适的
    async
    方法,那么可以直接
    wait
e、 例如,该代码行可以替换为:

await _userMailer.RegistrationConfirmation(user).SendAsync();
编辑:

由于
SendAsync
SmtpClient
上,因此您应该(使用)进入
等待
友好的API(使用):

公共静态任务SendTaskAsync(此SmtpClient客户端,邮件消息)
{
var tcs=new TaskCompletionSource();
SendCompletedEventHandler=null;
处理程序=(s,e)=>
{
client.sendpleted-=处理程序;
如果(e.Error!=null)tcs.TrySetException(e.Error);
否则,如果(如取消)tcs.TrySetCanceled();
else tcs.TrySetResult(null);
};
client.sendpleted+=处理程序;
client.SendAsync(消息,null);
返回tcs.Task;
}
然后您可以
等待
SmtpClient.SendTaskAsync
的结果


你不想使用
任务。运行
,因为这会导致你(正如我在博客上解释的那样)。

你的问题到底是什么?询问代码是否“好”是含糊不清的。这是处理电子邮件发送的正确方法吗。或者它会导致我以后出现问题。我收到一个错误,说明无法执行该操作。线程被阻止,这就是原因。在这种情况下,问题可能出在
sendsync
中。我将尝试直接从SmtpClient使用sendsync进行验证。类似的问题,现在我收到一个消息,说明异步模块或处理程序已完成,而异步操作仍处于挂起状态。我不能使用你的行:wait_userMailer.RegistrationConfirmation(user.SendAsync();它是空的。不能在空虚中等待。然而,Task.Run修复了这个问题。Is client.sendpleted-=handler;应该在外面的某个地方初始化。我得到一个错误,指出局部变量“handler”在访问之前可能没有初始化。
public static Task SendTaskAsync(this SmtpClient client, MailMessage message)
{
  var tcs = new TaskCompletionSource<object>();
  SendCompletedEventHandler handler = null;
  handler = (s,e) =>
  {
    client.SendCompleted -= handler;
    if (e.Error != null) tcs.TrySetException(e.Error);
    else if (e.Cancelled) tcs.TrySetCanceled();
    else tcs.TrySetResult(null);
  };
  client.SendCompleted += handler;
  client.SendAsync(message, null);
  return tcs.Task;
}