Last post Jul 24, 2015 01:38 AM by DonaldMark54
Dec 01, 2009 11:56 AM|km991148|LINK
I would like to implement some functionality to managage long running tasks and allow cancelation of such tasks by users.
I have already read the article here: http://msdn.microsoft.com/en-us/magazine/cc163380.aspx (Canceling Server Tasks with ASP.NET AJAX, Dino Esposito) but do not want to have to use an update panel or have to poll for the request (my original idea was to
use session to manage the variable to control the cancel, and poll for it before commiting the serverside db transaction).
However the server side api can be long running, is synchronous, and we do not have the option of converting them to an 'interuptable' task.
Therefore the idea was to use a module to handle the request, and within it get a handle on the running thread. We already have code that will take a thread, and use it to cancel any transactions on it (i.e. safer than using thread.abort). Is this possible
(i.e. getting the 'handle' on the thread, by some sort of id?
How does asp.net manage to service the threads used to process work, I imagine it must already do something similar?
cancelling threads modules
Dec 02, 2009 04:43 AM|km991148|LINK
I guess if no one can advise I must be lookign at this the wrong way :) ?
Jul 24, 2015 01:38 AM|DonaldMark54|LINK
Keep in mind that this solution presumes that you have framework 4.0 (or higher) and that you have the AJax Add-on for Visual Studio 2010:
I like complete examples that don't leave anything to your imagination. I looked everywhere on the web for this solution and found nothing very helpful. So. . . I had to develop it myself. To create this solution I started with this Microsoft webpage
and expanded on it. https://msdn.microsoft.com/en-us/library/dd997364(v=vs.100).aspx .
The msdn webpage can be a great place to start, but does not really get you a complete web solution to solve the probelm.
In the Html portion as you can see I only have two buttons, a label and timer. Pay close attention to the fact that on the second line down I have registered the AJAX assembly. This line can be copied exactly as you see it and put right under your page
declaration. The other thing you Should note is that I have the ScriptManager (for AJAX) as the first line inside the start of the Form tag. You should just copy everything on this page exactly as you see it and then only change the Name_of_My_Project to
whatever you named your solution.
Anyway here is the Html portion of my solution:
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Directory4.aspx.vb" Inherits="Name_of_My_Project.Directory4" %>
<%@ Register assembly="AjaxControlToolkit" namespace="AjaxControlToolkit" tagprefix="asp" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<asp:Button ID="btn_Start" runat="server" Text="Start" />
<asp:Button ID="btn_Stop" runat="server" Text="Stop" />
<asp:Label ID="lblMessages" runat="server"></asp:Label>
<asp:Timer ID="Timer1" runat="server" Enabled="False" Interval="3000">
Next you will want to copy in the code behind exactly as you see it here. For this solution I had to do several things to make it work. 1st was the Cancellation Token, 2nd was the ThreadPool and 3rd was the Timer. I had to use the Cancellation token just
to get it to cancel at all. Thread.Abort() did not work for me at all. All it did is make it look like it canceled the thread without really doing so. The Thread Pool was the other half of how I made it work. You can read up on how these things work, but
in the context of my example you should be able to figure it out. The Timer made it possible to know when the process actually completed on it's own without cancellation.
Here is my code behind portion.
Public Class Directory4
Private Shared cts As New CancellationTokenSource()
Private Shared cToken = cts.Token
Private Shared bAllDone As Boolean
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Protected Sub btn_Start_Click(sender As Object, e As EventArgs) Handles btn_Start.Click
' Pass the token to the cancelable operation.
ThreadPool.QueueUserWorkItem(New WaitCallback(AddressOf DoSomeWork), cToken)
Me.lblMessages.Text = "This Task has now started."
Timer1.Enabled = True
Protected Sub btn_Stop_Click(sender As Object, e As EventArgs) Handles btn_Stop.Click
btn_Start.Enabled = True
bAllDone = False
For i As Integer = 1 To 2000000
If bAllDone Then
Me.lblMessages.Text = "This Canceled Task has now been gently terminated."
'Thread 2: The Listener
Shared Sub DoSomeWork(ByVal obj As Object)
Dim i As Integer
Dim token As CancellationToken = CType(obj, CancellationToken)
For i = 0 To 10
' Simulating work.
If token.IsCancellationRequested Then
bAllDone = True
bAllDone = True
Protected Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
' '***** This is for ending the task normally.
If bAllDone Then
Me.lblMessages.Text = "This Task has now completed normally."
Timer1.Enabled = False
I hope this helps.