如何在 void 方法中使用异步

How can I use async in void method

我正在开发 Asp.Net 核心 MVC Web 应用程序,我必须每天检查是否有任何用户的“EndOfSubscription”结束。我必须将所有用户设置为“已过期”,然后向该用户发送电子邮件。

整个过程应该作为后台任务执行。现在,它每天都能成功运行,并将用户设置为“已过期”。但我的问题是如何在将用户设置为“已过期”后立即发送电子邮件。因为我必须使用 (await) 来发送电子邮件,但我知道将 (await) 用于 void 方法是一种不好的做法。我尝试了扩展方法,但它没有按预期工作。

这是我的启动文件。

    public void ConfigureServices(IServiceCollection services)
    {
       ---------- Lines of Code ----------
        services.AddSingleton<IEmailSender, EmailSender>();
        services.Configure<EmailOptions>(Configuration);
        services.AddHangfire(config => config.UseSqlServerStorage(Configuration.GetConnectionString("DefaultConnection")));
        services.AddHangfireServer();
        services.AddScoped<IExpirationJob, ExpirationJob>();
    }

    public void Configure(IApplicationBuilder app,
        IWebHostEnvironment env,
        IRecurringJobManager recurringJobManager,
        IServiceProvider serviceProvider)
    {
         ---------- Lines of Code ----------
        app.UseHangfireDashboard();
        //app.UseHangfireDashboard("/hangfire", new DashboardOptions()
        //{
        //    Authorization = new[] { new CustomAuthorizeFilter() }
        //});
        app.UseAuthentication();
        app.UseAuthorization();

        recurringJobManager.AddOrUpdate(
           "End Users Subscription",
           () => serviceProvider.GetService<IExpirationJob>().SetExpired(),
           Cron.Minutely
           );
    }
}

}

这是 ExpiredUsersServices 文件

 public interface IExpirationJob
{
    void SetExpired();
}


public class ExpirationJob : IExpirationJob
{
    private readonly ApplicationDbContext _db;
    private readonly IEmailSender _emailSender;

    public ExpirationJob(ApplicationDbContext db, IEmailSender emailSender)
    {
        _db = db;
        _emailSender = emailSender;
    }

    public void SetExpired()
    {
        foreach(var item in _db.Institution)
        {
            if (item.EndOfSubscriptionDate <= DateTime.Today) 
            {
                item.Status = SD.StatusExpired;

              //await _emailSender.SendEmailAsync( item.Admin.Email, "Your Account is Expired !", "Your subscription is over and your account is expired."); 
            }
        }
       await _db.SaveChangesAsync();
    }
}

感谢任何帮助。

您可以将任务设置为您的方法的 return 类型:

public interface IExpirationJob
{
    Task SetExpired();
}


public class ExpirationJob : IExpirationJob
{
    private readonly ApplicationDbContext _db;
    private readonly IEmailSender _emailSender;

    public ExpirationJob(ApplicationDbContext db, IEmailSender emailSender)
    {
        _db = db;
        _emailSender = emailSender;
    }

    public async Task SetExpired()
    {
        foreach(var item in _db.Institution)
        {
            if (item.EndOfSubscriptionDate <= DateTime.Today) 
            {
                item.Status = SD.StatusExpired;

              await _emailSender.SendEmailAsync( item.Admin.Email, "Your Account is Expired !", "Your subscription is over and your account is expired."); 
            }
        }
       await _db.SaveChangesAsync();
    }
}

使用这种方法,您必须更改此方法的调用方以等待它。