1

I'm trying to implement Async calls in a classic ASP.NET web page.

I'm following the instructions I've found here and I can get it to call asynchronously but I don't know how to cancel the execution of the async method when the request times out (which I can easily do by pausing execution of my code at a breakpoint).

My code so far is as follows:

  protected void Button_Click(object sender, EventArgs e)
    {
        PageAsyncTask task = new PageAsyncTask(OnBegin, OnEnd, OnTimeout, null);
        Page.RegisterAsyncTask(task);
        Page.AsyncTimeout = new TimeSpan(0, 0, 10);
        Page.ExecuteRegisteredAsyncTasks();
    }

    protected delegate void AsyncTaskDelegate();
    private AsyncTaskDelegate _dlgt;


    public IAsyncResult OnBegin(object sender, EventArgs e, AsyncCallback cb, object extraData)
    {
        _dlgt = new AsyncTaskDelegate(ExecuteAsyncTask);

        IAsyncResult result = _dlgt.BeginInvoke(cb, extraData);
        return result;
    }


    public void OnEnd(IAsyncResult ar)
    {
        _dlgt.EndInvoke(ar);
    }

    private void ExecuteAsyncTask()
    {
        MyObject obj = new MyObject();
        var task = obj.CompleteAsync();
        if (obj.Complete())
        {
            LabelResult.Text = "Success";
        }
        else
        {
            LabelResult.Text = "Failed";
        }
    }

    public void OnTimeout(IAsyncResult ar)
    {
        _dlgt.EndInvoke(ar);//this does not work!
    }

The main issue I have is that the code can "hang" at a certain point in the async method as I am calling an outside service and it can stop responding under certain situations.

Even if I try to EndInvoke the request the async code still runs.

Any help would be appreciated.

MatthewMartin
  • 32,326
  • 33
  • 105
  • 164
Guy Lowe
  • 2,115
  • 1
  • 27
  • 37

1 Answers1

1

OK so I I've worked it out. It has to do with cancellation tokens.

  1. First I created a CancellationTokenSource:

private System.Threading.CancellationTokenSource tokenSource = new System.Threading.CancellationTokenSource();

  1. Then I pass this into a Task factory to start the async task:

var task = System.Threading.Tasks.Task.Factory.StartNew(() => myObject.AsyncMethod(Request.QueryString, tokenSource.Token), tokenSource.Token);

  1. And finally when the timeout occurs I simple do this:

    public void OnTimeout(IAsyncResult ar) { tokenSource.Cancel(); tokenSource.Token.ThrowIfCancellationRequested(); }

VoilĂ !

This causes an exception which you then need to catch but at least this stops execution of any code.

Guy Lowe
  • 2,115
  • 1
  • 27
  • 37