locked
How can I use async in void method RRS feed

  • Question

  • User1554758465 posted

    I'm developing Asp.Net Core MVC Web Application where I have to check if "EndOfSubscription" of any user is over daily. I have to set all users as "Expired" and then send an email to that user.

    The whole process should be implemented as background task. Now, it works successfully everyday and it sets the users as "Expired" fine. But my problem is how can I send the email after setting the user as "Expired" immediately. Since I have to use (await) to send an email but I Knew that's a bad practice to use (await) for void methods. And i tried to do extension method but it didn't works as expected.

    Here is my startup file.

        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.Daily
               );
        }

    Here is ExpiredUsersServices file

    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();
        }
    }

    Sunday, November 8, 2020 3:08 PM

Answers

  • User475983607 posted

    Return "Task" not "void".  The official docs cover this.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, November 8, 2020 3:35 PM