-1

I have a long task that runs, and can take up to 15 minutes, I allow the user to only run one at a time. This all works well but I can't get my results and have a cancel button. Currently I have the cancel button write a file, and if that file is present during a loop, the task completes and self deletes. However, I can't get the results of the task to do anything, so errors aren't reported or anything. What is your recommendation on doing this?

Libraries needed for below (iirc)

using System
using System.Threading
using System.Threading.Tasks

Here is a rough example of my execution code.

protected void Execute_Click(object sender, EventArgs e)
{
    Task taskExecute = new Task(()=>
    {
        // 15 minute task
        // I also look for cancelation file during loop periodically.
    }
    taskExecute.Start();

    // If i wait for the task, it freezes the webpage so this is commented out
    // taskExecute.Wait();
}

here is my cancelation code:

protected void Cancel_Click(object sender, EventArgs e)
{
    //code to write file that long script looks for...
}

If you're wondering, the code is called via <asp:button onclick="Execute_Click"> calls. etc...

Also, I can click the cancel button if I refresh the page, but that defeats the purpose, as the responses in my results box won't be visible.

Robert Cotterman
  • 2,213
  • 2
  • 10
  • 19
  • Where is the rest of your code? – Chris Phillips Nov 02 '22 at 16:31
  • 1
    @ChrisPhillips what exactly you think is missing? OP showed that they have fire-and-forget long running task (granted, not correctly registered and likely to randomly be killed in the middle) and wish it to be cancelled from separate future request. (They also show how to do deadlock with Wait, not really sure for what purpose so). – Alexei Levenkov Nov 02 '22 at 16:35
  • Please advise on what code you need? Because i can't share what it's doing for security reasons – Robert Cotterman Nov 02 '22 at 16:35
  • @AlexeiLevenkov what do you mean not correctly registered? I also have script timeout to 20 minutes, which is longer than needed. But i definitely want to make it better, do you have a "registered correctly" link? – Robert Cotterman Nov 02 '22 at 16:41
  • In Web Forms, you don't just start tasks and run them. And if we zoom out a bit: a long running (often consider anything beyond a few seconds) HTTP request isn't a good idea. Web Servers are supposed to service HTTP requests, not do long running data processing. While there are some tools (such as [Hangfire](https://www.hangfire.io/) or [QueueBackgroundWorkItem](https://www.hanselman.com/blog/how-to-run-background-tasks-in-aspnet)), they're not ideal. Instead, move that processing to a different app. Often the work would get pushed into a queue (such as RabbitMQ, AWS SQS, Azure ServiceBus etc – mason Nov 02 '22 at 16:51
  • @RobertCotterman you likely already searched for "C# asp.net long running tasks" and already seen posts like https://stackoverflow.com/questions/2519756/long-running-asp-net-tasks and https://stackoverflow.com/questions/5553001/how-should-i-perform-a-long-running-task-in-asp-net-4. TL;DR - asp.net is not really setup for those even if there is some support with QueueBackgroundWorkItem. – Alexei Levenkov Nov 02 '22 at 16:51
  • , then some other app would read the work from the queue, process it, and notify the web application when it's done. It takes bit more work, but is a much more scalable and stable way of doing things. That "other app" could be an Azure Function, AWS Lambda, a Windows Service, or some other type of app. – mason Nov 02 '22 at 16:52
  • Ah I didn't realize it was asp.net (probably because that edit was added after I started my answer). Tasks don't really work well with it. At my job I use [Hangfire](https://www.hangfire.io/) which does work pretty well. – Jesse Nov 02 '22 at 16:52
  • Thanks for the help guys, I actually basically wrote hangfire into my code lol. Didn't know there were programs for it, but where I work, I have to use what is available, and can't get outside other files. I have limits and everything built in, it's a very VERY low traffic problem, and the tasks aren't demanding, it just has to do it 50 times. and so it takes about 10 minutes, but most the task is an API call. So it's waiting on other servers. – Robert Cotterman Nov 02 '22 at 16:56
  • There is identical question https://stackoverflow.com/questions/6622368/cancel-a-long-task-thats-managed-by-a-web-service but I don't think it is useful duplicate as it does not really answer the main question - how to really get cancellation token to next request... – Alexei Levenkov Nov 02 '22 at 16:57

1 Answers1

0

What you're looking for can be accomplished with Azure Durable Functions and add in SignalR/Websockets if you're looking to track state in real-time without polling.

Calls to durable functions return with an ID that you can check on intermittently using a built-in state management endpoint on your function. State objects support custom data as well. This loose coupling allows you to execute and forget calls to the API without blocking any threads. Each call returns a unique ID, so you can run multiple instances in parallel, and easily track them. Connect your web client and web service to a websockets channel (SignalR), and you can send real-time updates or events from your webservice TO your webclient, including a "process completed" event that you can use to trigger the download/render of output/logs/etc...

Chris Phillips
  • 1,997
  • 2
  • 19
  • 34
  • I am not using Azure, but thank you for the help. I found that if I make the task a background task, and have it look for a file, i can then make the cancel button place that cancel file to trigger a cancellation. pretty neat. – Robert Cotterman Nov 23 '22 at 03:37