错误:异步操作仍处于挂起状态时,异步模块或处理程序已完成
我有一个Controller Action方法来保存用户详细信息,如下所示。
public async Task SaveUser(ViewModel.VM_CreateUser user) { var result = await _user.Save(userDetails); return Json(new { Success = String.IsNullOrEmpty(result) }); }
到目前为止,上述4行function没有问题。
public async Task SaveUser(ViewModel.VM_CreateUser user) { var result = await _user.Save(userDetails); new MailController().CreateUser(user.userDetails); //<==This is problem line of code. }
以下是我的邮件控制器。
public class MailController : MailerBase { public void CreateUser(ViewModel.VM_User user) { To.Add(user.EmailAddress); From = System.Configuration.ConfigurationManager.AppSettings["emailSender"]; Subject = "Hi"; Email("CreateUser", user).DeliverAsync(); } }
在上面的代码中,我在执行电子邮件发送代码时遇到问题。 我收到以下错误消息。
在异步操作仍处于挂起状态时完成异步模块或处理程序
请建议纠正措施!!
DeliverAsync是否返回任务? 如果是的话,试试这个。
public class MailController : MailerBase { public async Task CreateUserAsync(ViewModel.VM_User user) { To.Add(user.EmailAddress); From = System.Configuration.ConfigurationManager.AppSettings["emailSender"]; Subject = "Hi"; await (Email("CreateUser", user).DeliverAsync()); } }
然后在您的控制器中,等待CreateUserAsync返回的任务。
public async Task SaveUser(ViewModel.VM_CreateUser user) { var result = await _user.Save(userDetails); await (new MailController().CreateUserAsync(user.userDetails)); return Json(new { Success = String.IsNullOrEmpty(result) }); }
注意:如果你的目标是让电子邮件发送背景并忘记操作,那就不是了。
这是因为async
方法跟踪它们的完成,甚至是async void
。 他们通过在启动时注册SynchronizationContext
并在返回时标记操作完成来完成此操作。 ASP.NET跟踪所有创建的操作,并要求在操作返回之前完成所有操作,否则它会向HTTP客户端返回错误。 如果需要运行“fire and forget”方法,则必须手动避免在ASP.NET SynchronizationContext
上启动它。 例如, await Task.Run(() => CallFireAndForget())
( await
等待同步部分运行。这是有效的,因为该方法是async void
。要触发async Task
即发射,忘记,你必须明确地避免将Task
返回到Task.Run()
如下所示: await Task.Run(() => { CallFireAndForgetAsync(); })
)。
获取相同错误消息的另一种方法应该是在异步操作中写入:
// BAD CODE, DEMONSTRATION ONLY! AsyncOperationManager.CreateOperation();
如果使用AsyncOperation
API,则必须确保在允许action方法返回之前调用AsyncOperation.OperationCompleted()
。
在您的情况下,如果邮件发送确实是一个即发即弃的任务,您可以在将其签名更改为async Task CreateUserAsync(ViewModel.VM_User user)
后,在CreateUser
内部执行以下async Task CreateUserAsync(ViewModel.VM_User user)
:
await Task.Run(() => Email("CreateUser", user).DeliverAsync());
在你的行动中:
await new MailController().CreateUserAsync(user.userDetails);
理想情况下,你不会使用Task.Run()
的东西。 相反,您可以暂时替换当前的SynchronizationContext
:
上述就是C#学习教程:错误:异步操作仍处于挂起状态时,异步模块或处理程序已完成分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注—计算机技术网(www.ctvol.com)!
var originalSynchronizationContext = SynchronizationContext.Current; try { SynchronizationContext.SetSynchronizationContext(null); new MailController().CreateUser(user.userDetails); } finally { SynchronizationContext.SetSynchronizationContext(originalSynchronizationContext); }
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/998253.html