首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Async ActionMethod -是否正确

Async ActionMethod -是否正确
EN

Stack Overflow用户
提问于 2013-01-02 14:13:13
回答 1查看 428关注 0票数 1

仅仅因为某件事有效并不意味着它是正确的。所以我想要一些关于以下代码的反馈。

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

代码语言:javascript
复制
 [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");
    }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2013-01-02 22:16:13

我不确定ASP.NET线程被阻塞会导致什么样的“问题”,但是关于您的async/await代码:

new CancellationToken(false)中没有意义,这和CancellationToken.None是一样的,这就像不提供parameter.

  • There的cancellationToken可能没有指向Task.Run一样,它在线程池线程上执行SendAsync。如果SendAsync是一个合适的async方法,那么它可以直接被await

例如,该行代码可以替换为:

代码语言:javascript
复制
await _userMailer.RegistrationConfirmation(user).SendAsync();

编辑:

由于SendAsyncSmtpClient上,您应该使用wrap this API (使用Event-based Asynchronous Pattern)进入await-friendly应用程序接口(使用Task-based Asynchronous Pattern):

代码语言:javascript
复制
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;
}

然后您可以对SmtpClient.SendTaskAsync的结果执行await操作。

您不想使用Task.Run,因为这会导致您使用return early from ASP.NET requests, which is a dangerous practice (正如我在我的博客中所解释的那样)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/14117633

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档