-1

I made an endpoint to send messages to users but the request didn't complete successfully and aborted after some time before it ends

the service usually takes at least two hours running to finish.

below is my code I used task.run to run it in the background.

var task = Task.Run(() => new MessageManger().Send(message));
return View(new messageDTO()); 
Ahmed
  • 3
  • 7
  • That isn’t enough code to give us any idea what is happening. – Sami Kuhmonen Dec 20 '19 at 12:56
  • 1
    You are doing a fire-and-forget which is probably what you intend, but the request ends before the task has a chance to run. I would just send the message synchronously, it is bad practice to `Task.Run()` in asp.net anyway. – Crowcoder Dec 20 '19 at 12:58
  • the request may take 2 hours to be end and the user will not wait for 2 hours to see what is happened – Ahmed Dec 20 '19 at 13:09
  • You can't run long running processes in asp.net from a request like that. This sounds like it should be offloaded to a distributed system. You might look at something like HangFire but to me that's hacky. – Crowcoder Dec 20 '19 at 13:16
  • thanks guys for you effort to help me out after searching I've scheduled a background job with singleton design pattern and it worked fine. @Crowcoder you're right as it is not recommended to run long processes in asp.net especially when it matters to http request. – Ahmed Jun 11 '20 at 05:36

2 Answers2

0

If you have to use a task, you can try adopting this, pay attention to the last 3 parameters, they might not suit your requirements.

 Task.Factory.StartNew(
                        () =>
                            WriteMessageInBackground(invoicesIn.Split(','),  _messageController, chkSms.Checked,
                                chkEmail.Checked, messageTemplate),
                        CancellationToken.None,
                        TaskCreationOptions.PreferFairness,
                        TaskScheduler.Default);

It returns straight away, but its important to understand, that the WriteMessageInBackground method is simply bulk writing the messages into a table, we have another component that's picking them up for sending, as the mail server, in particular likes to take its own damn time some days. As mentioned in the comments, if this job is really long running, it really needs to be handed off to something other than a website to run it.

GerryFC
  • 56
  • 6
  • 2
    I still would not recommend using another thread pool thread just to drop a message on a queue or whatever it is. That should be a very fast operation that doesn't need to be asynchronous. With this approach you still risk the request/response to end before the message is written. – Crowcoder Dec 20 '19 at 14:16
  • Its a user assembled list with a max of 9,999 recipients that can take up to a minute or two by the time all is done. The idea is the page returns immediately and the user can check on it via another page to see how its getting on. It is planned to refactor this at some stage but for the moment, its exactly what they want. – GerryFC Dec 20 '19 at 15:36
  • That's what [HostingEnvironment.QueueBackgroundWorkItem Method](https://learn.microsoft.com/en-us/dotnet/api/system.web.hosting.hostingenvironment.queuebackgroundworkitem) is for. – Paulo Morgado Dec 20 '19 at 17:07
  • Thanks, this doesn't work with the version of .Net used in the above solution, so that's another days work. :( – GerryFC Jan 02 '20 at 10:18
  • thanks guys for you effort to help me out at the end, I scheduled a background job with singleton design pattern and it worked fine. – Ahmed Jun 11 '20 at 05:33
0

So you're starting a background thread that takes ~2 hours to complete, and it's not finishing.

A couple things could be happening:

  1. An exception is happening that you can't see because it's not reported.
  2. By default, IIS is configured to shut down the app pool after 20 minutes of not getting any new incoming requests. It does know if a request is still being processed, but it has no idea there's a background thread running, so your app could be killed halfway through that background job.

My bet is on #2. You can configure the app pool to never shut down, but ASP.NET simply isn't designed for long-running background tasks. You still have reasons to manually recycle the app pool, and you'll have no idea if a background task is still running. You're better off putting the job in a queue in a database and using a Windows Service to pick those up and process them.

Gabriel Luci
  • 38,328
  • 4
  • 55
  • 84
  • yeah it's because the second one as the request should have been taken more than 2 hours so the IIS killed this process before it ends. thanks buddy for you efforts. – Ahmed Jun 11 '20 at 05:38