0

General question. A webpage is served to a user, data goes in n out for that session. In c# and asp.net, how can u create a page on server that continually does a task and also has only 1 instance running. it does something over and over. Then as needed a person could view what it's doing.

Strider489
  • 67
  • 1
  • 11

1 Answers1

0

You can run a long task in a separate thread and communicate with it when you need. something like this.

protected void btnRun_Click(object sender, EventArgs e)
{
    var jobState = new StateInfo()
    {
        Id = 1,
        Counter = 0,
        Content = "Start the job",
        Cancelled = false,
        Completed = false
    };
    Session["job"] = jobState;
    System.Threading.ThreadPool.QueueUserWorkItem(
        new System.Threading.WaitCallback(LongJob),
        jobState
        );//returns immediately
    lblToken.Text += "<br />" + jobState.Counter.ToString() 
        + " Completed: " + jobState.Completed.ToString()
        + " Cancelled: " + jobState.Cancelled.ToString()
        + "<br />" + jobState.Content;
    btnCancel.Visible = true;
    btnCheck.Visible = true;
}

protected void btnCancel_Click(object sender, EventArgs e)
{
    var jobState = Session["job"] as StateInfo;
    if (!jobState.Completed)
        jobState.Cancelled = true;
    System.Threading.Thread.Sleep(1000);//wait for the next loop to complete
    lblToken.Text += "<br />" + jobState.Counter.ToString()
        + " Completed: " + jobState.Completed.ToString()
        + " Cancelled: " + jobState.Cancelled.ToString()
        + (jobState.Completed || jobState.Cancelled ? "<br />" + jobState.Content : "");
}

protected void btnCheck_Click(object sender, EventArgs e)
{
    var jobState = Session["job"] as StateInfo;
    lblToken.Text += "<br />" + jobState.Counter.ToString()
        + " Completed: " + jobState.Completed.ToString()
        + " Cancelled: " + jobState.Cancelled.ToString()
        + (jobState.Completed || jobState.Cancelled ? "<br />" + jobState.Content : "");
}

private void LongJob(object state)
{
    var jobState = state as StateInfo;
    do
    {
        System.Threading.Thread.Sleep(1000);
        jobState.Counter++;
        if (jobState.Counter >= 100)
        {
            jobState.Completed = true;
            jobState.Content = "The job is completed";
        }
        else if (jobState.Cancelled)
            jobState.Content = "The job is cancelled";
    }
    while (!jobState.Cancelled && !jobState.Completed);
}
[Serializable]
class StateInfo
{
    public int Id { get; set; }
    public int Counter { get; set; }
    public string Content { get; set; }
    public bool Cancelled { get; set; }
    public bool Completed { get; set; }
}

and obvious client controls.

<asp:Label ID="lblToken" runat="server"></asp:Label><br />
<asp:Button runat="server" ID="btnRun" OnClick="btnRun_Click" Text="Run" />
<asp:Button runat="server" ID="btnCheck" OnClick="btnCheck_Click" Text="Check State" Visible="false" />
<asp:Button runat="server" ID="btnCancel" OnClick="btnCancel_Click" Text="Cancel" Visible="true" />
Alex Kudryashev
  • 9,120
  • 3
  • 27
  • 36
  • 2
    Be careful with just starting up a Thread. Depending on server configuration if there are no incoming requests it may kill the process and not complete the work you gave it. The better thing to do is either use a library designed to do background work (I like [Hangfire](https://www.hangfire.io/) or if you are using ASP.NET Core using a [IHostedService](https://learn.microsoft.com/en-us/aspnet/core/fundamentals/host/hosted-services?view=aspnetcore-2.2) to tell ASP.NET that there is work being done that should not be killed. – Scott Chamberlain Jun 02 '19 at 01:20
  • I am not familiar with threading in web apps. Thank you for this info, I will most definitely look more into it. – Strider489 Jun 02 '19 at 02:13
  • @Michael I would avoid Thread.Sleep at all costs in any production application. https://stackoverflow.com/questions/8815895/why-is-thread-sleep-so-harmful) – William Xifaras Jun 02 '19 at 19:15
  • @WilliamXifaras `Thread.Sleep` is just a simulation of long task for demonstration and test purposes. ;) – Alex Kudryashev Jun 02 '19 at 23:06