Home > Software design >  Using Task ContinueWith to delay execution of code
Using Task ContinueWith to delay execution of code

Time:02-03

I need to add delay to some code block. I am using Task ContinueWith to achieve that, it works as expected when tested on my machine but the deployed code is not working.

public void DailyReminder()
{        
    //Do somethings
    System.Threading.Tasks.Task.Delay(300000).ContinueWith(t => EmailAlert());  //This should not block UI   
    //Do more things, this should not wait for 300000 ms to get excecuted
}

public void EmailAlert()
{
    //Send Email
}

For Example i need the below code to produce A B C and D only after the 5 sec delay -

using System;
using System.Threading.Tasks;

namespace HelloWorld
{
  class Program
  {
    static void Main(string[] args)
    {      
    Console.WriteLine("A");
      EmailAlert();
       Console.WriteLine("C");
    }
    
    private static async Task EmailAlert()
    {
    Console.WriteLine("B");    
        await Task.Delay(5000);
        Console.WriteLine("D");    
        }
  }
}

CodePudding user response:

You should separate your EmailAlert (which is a fire-and-forget task) and the logic that is not dependent on the task.

public void DailyReminder()
{
  // A discard pattern to make it explicit this is a fire-and-forget
  _ = EmailAlert();
  
  // Additional code that does not depend on the preceding task
}

public async Task EmailAlert()
{
  await Task.Delay(300_000);
  // await Some email sending logic
}

CodePudding user response:

I'm not sure of where in your code you are trying to create this delay, but you normally don't have the control over how long a thread will be alive when deploying your application to a server.

Normally a thread is created when a user sends a request to the application, and when it returns its response the thread will be stopped.

Also, the web server may close down the entire application when there's no traffic for a while.

The solution for these long running methods is to use Worker services.

You can read more from the documentation at https://learn.microsoft.com/en-us/dotnet/core/extensions/workers

CodePudding user response:

it works as expected when tested on my machine but the deployed code is not working.

If you're using some kind of shared or cloud hosting, it's normal to have your app shut down when it's done servicing requests for some time. This is why fire-and-forget on ASP.NET is dangerous.

Since you definitely want your email to be sent, fire-and-forget is not an appropriate solution. Instead, you want a basic distributed architecture:

  • Instead of sending the email from ASP.NET, serialize it to a message sent to a durable queue.
  • Have a separate background process read that queue and send the actual email.

CodePudding user response:

You try use case this :

 public void DailyReminder()
{        
    //Do somethings
    System.Threading.Tasks.Task.Delay(300000).ContinueWith(t => EmailAlert()).Wait();  //This should not block UI   
    //Do more things, this should not wait for 300000 ms to get excecuted
}

public void EmailAlert()
{
    //Send Email
}
  • Related