Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7638055
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 31, 20262026-05-31T08:04:52+00:00 2026-05-31T08:04:52+00:00

I have a long running operation which I am putting on a background thread

  • 0

I have a long running operation which I am putting on a background thread using TPL. What I have currently works but I am confused over where I should be handling my AggregateException during a cancellation request.

In a button click event I start my process:

private void button1_Click(object sender, EventArgs e)
{
    Utils.ShowWaitCursor();
    buttonCancel.Enabled = buttonCancel.Visible = true;
    try
    {
        // Thread cancellation.
        cancelSource = new CancellationTokenSource();
        token = cancelSource.Token;

        // Get the database names.
        string strDbA = textBox1.Text;
        string strDbB = textBox2.Text;

        // Start duplication on seperate thread.
        asyncDupSqlProcs =
            new Task<bool>(state =>
                UtilsDB.DuplicateSqlProcsFrom(token, mainForm.mainConnection, strDbA, strDbB),
                "Duplicating SQL Proceedures");
        asyncDupSqlProcs.Start();

        //TaskScheduler uiThread = TaskScheduler.FromCurrentSynchronizationContext();
        asyncDupSqlProcs.ContinueWith(task =>
            {
                switch (task.Status)
                {
                    // Handle any exceptions to prevent UnobservedTaskException.             
                    case TaskStatus.Faulted:
                        Utils.ShowDefaultCursor();
                        break;
                    case TaskStatus.RanToCompletion:
                        if (asyncDupSqlProcs.Result)
                        {
                            Utils.ShowDefaultCursor();
                            Utils.InfoMsg(String.Format(
                                "SQL stored procedures and functions successfully copied from '{0}' to '{1}'.",
                                strDbA, strDbB));
                        }
                        break;
                    case TaskStatus.Canceled:
                        Utils.ShowDefaultCursor();
                        Utils.InfoMsg("Copy cancelled at users request.");
                        break;
                    default:
                        Utils.ShowDefaultCursor();
                        break;
                }
            }, TaskScheduler.FromCurrentSynchronizationContext()); // Or uiThread.

        return;
    }
    catch (Exception)
    {
        // Do stuff...
    }
}

In the method DuplicateSqlProcsFrom(CancellationToken _token, SqlConnection masterConn, string _strDatabaseA, string _strDatabaseB, bool _bCopyStoredProcs = true, bool _bCopyFuncs = true) I have

DuplicateSqlProcsFrom(CancellationToken _token, SqlConnection masterConn, string _strDatabaseA, string _strDatabaseB, bool _bCopyStoredProcs = true, bool _bCopyFuncs = true)
{ 
    try
    {
        for (int i = 0; i < someSmallInt; i++)
        {
            for (int j = 0; j < someBigInt; j++)
            {
                // Some cool stuff...
            }

            if (_token.IsCancellationRequested)
                _token.ThrowIfCancellationRequested();
        }
    }
    catch (AggregateException aggEx)
    {
        if (aggEx.InnerException is OperationCanceledException)
            Utils.InfoMsg("Copy operation cancelled at users request.");
        return false;
    }
    catch (OperationCanceledException)
    {
        Utils.InfoMsg("Copy operation cancelled at users request.");
        return false;
    }
}

In a button Click event (or using a delegate (buttonCancel.Click += delegate { /Cancel the Task/ }) I cancel theTask` as follows:

private void buttonCancel_Click(object sender, EventArgs e)
{
    try
    {
        cancelSource.Cancel();
        asyncDupSqlProcs.Wait();
    }
    catch (AggregateException aggEx)
    {
        if (aggEx.InnerException is OperationCanceledException)
            Utils.InfoMsg("Copy cancelled at users request.");
    }
}

This catches the OperationCanceledException fine in method DuplicateSqlProcsFrom and prints my message, but in the call-back provided by the asyncDupSqlProcs.ContinueWith(task => { ... }); above the task.Status is always RanToCompletion; it should be cancelled!

What is the right way to capture and deal with the Cancel() task in this case. I know how this is done in the simple cases shown in this example from the CodeProject and from the examples on MSDN but I am confused in this case when running a continuation.

How do I capture the cancel task in this case and how to ensure the task.Status is dealt with properly?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-31T08:04:54+00:00Added an answer on May 31, 2026 at 8:04 am

    You’re catching the OperationCanceledException in your DuplicateSqlProcsFrom method, which prevents its Task from ever seeing it and accordingly setting its status to Canceled. Because the exception is handled, DuplicateSqlProcsFrom finishes without throwing any exceptions and its corresponding task finishes in the RanToCompletion state.

    DuplicateSqlProcsFrom shouldn’t be catching either OperationCanceledException or AggregateException, unless it’s waiting on subtasks of its own. Any exceptions thrown (including OperationCanceledException) should be left uncaught to propagate to the continuation task. In your continuation’s switch statement, you should be checking task.Exception in the Faulted case and handling Canceled in the appropriate case as well.

    In your continuation lambda, task.Exception will be an AggregateException, which has some handy methods for determining what the root cause of an error was, and handling it. Check the MSDN docs particularly for the InnerExceptions (note the “S”), GetBaseException, Flatten and Handle members.


    EDIT: on getting a TaskStatus of Faulted instead of Canceled.

    On the line where you construct your asyncDupSqlProcs task, use a Task constructor which accepts both your DuplicateSqlProcsFrom delegate and the CancellationToken. That associates your token with the task.

    When you call ThrowIfCancellationRequested on the token in DuplicateSqlProcsFrom, the OperationCanceledException that is thrown contains a reference to the token that was cancelled. When the Task catches the exception, it compares that reference to the CancellationToken associated with it. If they match, then the task transitions to Canceled. If they don’t, the Task infrastructure has been written to assume that this is an unforeseen bug, and the task transitions to Faulted instead.

    Task Cancellation in MSDN

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have a long running series of operations in a .NET 2.0 BackgroundWorker thread.
i have a long running function¹: public string FindPasswordFromHash(String hash) { ... } which
I have some long running scripts with breaks requiring input/interaction to continue but when
I have UI which displaying status of long-running operations (downloading some text files from
I have an Android app, in which Activities fire long running operations that run
I have a Windows service which performs a fairly long running task. At the
Motivation I have a long-running boolean function which should be executed in an array
I have a long-running cleanup operation that I need to perform in onDestroy() of
I have a long running SQL statement that I want to run, and no
I have a long running process in VB6 that I want to finish before

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.