Search code examples
c#asp.net.netmultithreadingbackground-process

HostingEnvironment.QueueBackgroundWorkItem - Clarification?


I've read Stephen's article about fire and forget background actions in Asp.net.

It is not recommended to use Task.Run for fire-and-forget because Asp.net doesn't know that you've queued a task.

So if a recycle is about to occur, the task has no way of knowing it.
That's where HostingEnvironment.QueueBackgroundWorkItem gets in.

It will know that a recycle is about to happen and will invoke the Cancellation Token.

But!

FWIK - Background tasks are being "terminated" once the main thread has finished.

That means that if a request gets in (a new thread is being created/fetched) and it invokesTask.Run , and the response has finished (but Task has not) then the Task will be terminated.

Question:

Does QueueBackgroundWorkItem solve this problem ? or does it only exist to warn about recycle? In other words, if there's a request which runs QueueBackgroundWorkItem and the response has finished, will the QueueBackgroundWorkItem continue to execute its code?

The docs say: " independent of any request", but I'm not sure if it answers my question though


Solution

  • According to the documentation, this method tries to delay application shutdown until background work has completed.

    Differs from a normal ThreadPool work item in that ASP.NET can keep track of how many work items registered through this API are currently running, and the ASP.NET runtime will try to delay AppDomain shutdown until these work items have finished executing.

    Also, it does not flow certain contexts which are associated with the current request and are inappropriate for request-independent background work:

    This overloaded method doesn't flow the ExecutionContext or SecurityContext from the caller to the callee. Therefore, members of those objects, such as the CurrentPrincipal property, will not flow from the caller to the callee.

    In ASP.NET there is no way to make sure that background work ever completes. The machine could blue screen, there could be a bug terminating the worker process, there could be a timeout forcing termination and many other things.

    Or, your code could have a bug and crash. That causes the queued work to be lost as well.

    If you need something executed reliably, execute it synchronously before confirming completion, or queue it somewhere (message queue, database, ...).

    That means that if a request gets in (a new thread is being created/fetched) and it invokesTask.Run, and the response has finished (but Task has not) then the Task will be terminated.

    No, Task.Run works independently of HTTP requests. In fact, there is no way to cancel a Task except if the task's code cancels itself.