Getting QueueBackgroundWorkItem to complete if the web page is closed

旧时模样 提交于 2019-12-11 08:28:39

问题


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:


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:



来源:https://stackoverflow.com/questions/49280652/getting-queuebackgroundworkitem-to-complete-if-the-web-page-is-closed

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!