在ASP.NET MVC Controller中的单个方法中异步调用多个方法

时间:2019-05-13 12:59:39

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

ASP.NET MVC应用程序中,我的Service.cs中有两个方法,如下所示(为简便起见简化了方法),我想使用async异步调用这些方法。但是从Controller调用第一个方法(保存)之后,我也想返回此操作的结果,而不必等待第二个方法(SendEmail)。但是在这种情况下,我必须返回结果,并且不知道如何使用ASP.NET MVC异步来管理它。您能否针对这种情况提供一些建议?我想我必须在所有链方法中使用async,但不确定如何构建此链。任何帮助,将不胜感激。

控制器:

public JsonResult AddRecord() {
var result = service.Save();
//I need to return the result after record is added (without waiting the email sent)

service.SendEmail();    
}

服务:

public MyEntity Save() {
    //
}


public void SendEmail() {
    //
}

4 个答案:

答案 0 :(得分:2)

我可以考虑的场景。使用匿名任务

public JsonResult AddRecord() {
var result = service.Save();
//I need to return the result after record is added (without waiting the email sent)

Task.Run(() => service.SendEmail()); 
return result;
}

第二种情况是使您的SendEmail方法异步,这样,它将与任务内容几乎相同,通常说使用异步方法不是一个好主意,但我认为这种特殊情况符合条件

答案 1 :(得分:1)

您可以尝试这样做:

public class Service
{
    public Task<MyEntity> SaveAsync()
    {
        return Task.Run(() => Save());
    }

    public MyEntity Save()
    {
        Thread.Sleep(2000);
        var entity = new MyEntity();
        return entity;
    }

    public Task SendEmailAsync()
    {
        return Task.Run(() => SendEmail());
    }

    public void SendEmail()
    {
        Thread.Sleep(2000);
        Console.WriteLine("The message is sent");
    }
}

并创建Controller或其他服务,其中一些:

public class SomeController
{
    private readonly Service _service;

    public SomeController()
    {
        _service = new Service();
    }

    public MyEntity AddRecord()
    {
        var resultTask = _service.SaveAsync();
        _service.SendEmailAsync();

        return resultTask.Result;
    }

    public async Task<MyEntity> AddRecord2()
    {
        var resultTask = _service.SaveAsync();

        _service.SendEmailAsync();

        //var result = await resultTask;
        //return result;

        return await resultTask;
    }
}

答案 2 :(得分:0)

听起来您想从其他线程调用SendMail()。 尝试研究有助于后台工作的Hangfire

答案 3 :(得分:0)

一种方法是更改​​SendEmail的行为及其名称,以使其实际上不发送电子邮件。它添加了将电子邮件发送到队列的请求。您的方法调用可能类似于:

service.QueueEmail(someData);

这不需要是异步的(也没有好处),因为您要做的只是向队列中添加内容。一个单独的过程从队列中读取并发送电子邮件。

这将使您的服务更加集中。知道如何发送电子邮件的更详细的代码将存在于其他地方。然后,该代码可以更有效地处理这种复杂性。例如,它可以合并重试逻辑。当您的应用程序中有其他进程发送电子邮件时,他们可以重新使用该进程。