1

According to literature I've read about QueueBackgroundWorkItem, I should be able to complete a long task in the background without being interrupted by IIS.

What I'm wondering if is possible, if I start a long task and close my website before it completes, shouldn't the QueueBackgroundWorkItem finish the task? (it's not currently)

Here are my calls:

private async Task WriteTextAsync(CancellationToken cancellationToken)
{
    string filePath = printPath;
    string text;
    byte[] encodedText = Encoding.Unicode.GetBytes(text);

    for (int i = 0; i < 200; i++)
    {
        text = "Line " + i + "\r\n";
        encodedText = Encoding.Unicode.GetBytes(text);
        using (FileStream sourceStream = new FileStream(filePath, FileMode.Append, FileAccess.Write, FileShare.None,                    bufferSize: 4096, useAsync: true))
        {
            await sourceStream.WriteAsync(encodedText, 0, encodedText.Length);
        };
        Thread.Sleep(200);
    }
}

private void QueueWorkItem()
{
    Func<CancellationToken, Task> workItem = WriteTextAsync;
    HostingEnvironment.QueueBackgroundWorkItem(workItem);
}

EDIT: I have gotten this to work. I trimmed it up. This now executes after the browser is closed, about 3-4 minutes, everything is written to file. Thanks for all who chipped in.

private void QueueWorkItem()
{
    HostingEnvironment.QueueBackgroundWorkItem(cancellationToken =>
    {
        string filePath = printPath;
        string text = "File line ";
        TextWriter tw = new StreamWriter(printPath);

        for (int i = 0; i < 400; i++)
        {
            text = "Line " + i;

            tw.WriteLine(text);

            Thread.Sleep(200);
        }

        tw.Close();
    });
}
  • 1
    This all happens server side, closing your browser has no effect on the server (full stop) – Liam Mar 14 '18 at 14:45
  • 1
    you might also want to look at using [Hangfire](https://www.hangfire.io/) for managing long running tasks. – Fran Mar 14 '18 at 15:26

1 Answers1

6

When you use HostingEnvironment.QueueBackgroundWorkItem, you have to keep in mind that the task is running in asp.net worker process. So if IIS shuts the worker process down after 20 minutes of no requests (this is the default), then your task will go down as well.

If your background task should run every X time, then it would be a good idea to add it to global.asax Application_Start. Something like this:

In global.asax Application_Start:

System.Web.Hosting.HostingEnvironment.QueueBackgroundWorkItem(async (t) => { await BackgroundJob.RunAsync(t); });

Your background class:

public static class BackgroundJob
{
   public static async Task RunAsync(CancellationToken token)
   {
      ... your code

      await Task.Delay(TimeSpan.FromMinutes(5), token);
   }
}

IIS application pool configuration

In app pool advanced settings, change Idle timeout to zero, so your background task will not stop running when you have no request for a period of time:

enter image description here

Rodrigo Werlang
  • 2,118
  • 1
  • 17
  • 28