Christopher Painter
Christopher Painter

Reputation: 55591

Handle Cancellation Request in Custom Code Activity

I have a long running process in a custom code activity. If I attempt to stop the build while this activity is running I get back the error:

TFS215104: Failed to stop build XXXXXXXXXXXXX: it did not respond to a workflow cancellation request.

Then in the build log I see:

Cannot stop the build. Details: Operation did not complete in 00:00:59.9843747.

Cannot cancel the workflow. Agent needs to be restarted. Details: The operation did not complete within the allotted timeout of 00:01:00. The time allotted to this operation may have been a portion of a longer timeout.

Service 'XXXXXXX - Controller': build 'XXXXXXXXXXX' was stopped. Details: Build was cancelled.

How does this cancellation request make it back to my activity? I understand how to use background processes but I'm not sure how to capture the cancellation request inside my code.

Upvotes: 1

Views: 1191

Answers (2)

Christopher Painter
Christopher Painter

Reputation: 55591

It seems all the blogs I read showed how to use CodeActivity instead of AsyncCodeActivity. Here is an example:

[BuildActivity(HostEnvironmentOption.All)]
    public partial class SourceCodeAnalysisAsync : AsyncCodeActivity
    {
        private CodeActivityContext _context;
        private bool _continue = true;

        protected override IAsyncResult BeginExecute(AsyncCodeActivityContext context, AsyncCallback callback, object state)
        {
            _context = context;
            var  doSomethingDelegate = new Action(DoSomething);
            context.UserState = doSomethingDelegate;
            return doSomethingDelegate.BeginInvoke(callback, state);
        }

        protected override void Cancel(AsyncCodeActivityContext context)
        {
            base.Cancel(context);
            _continue = false;
        }

        protected override void EndExecute(AsyncCodeActivityContext context, IAsyncResult result)
        {
            var doSomethingDelegate = (Action)context.UserState;
            doSomethingDelegate.EndInvoke(result);
        }

        private void DoSomething()
        {
            if (File.Exists(@"C:\test.txt"))
            {
                File.Delete(@"C:\test.txt");
            }

            int i = 0;
            do
            {
                File.AppendAllText(@"C:\test.txt", string.Format("do something {0}\r\n", i));
                Thread.Sleep(1000);
                i++;
            } while (_continue && i < 30);
        }
    }

Upvotes: 1

Mike
Mike

Reputation: 2115

Are you using the CodeActivity class as your base?

According to this, you might try AsyncCodeActivity as it supports Cancel.

Upvotes: 1

Related Questions