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 8595581
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 12, 20262026-06-12T00:28:10+00:00 2026-06-12T00:28:10+00:00

When using tasks for large/long running workloads that I need to be able to

  • 0

When using tasks for large/long running workloads that I need to be able to cancel I often use a template similar to this for the action the task executes:

public void DoWork(CancellationToken cancelToken)
{
    try
    {
        //do work
        cancelToken.ThrowIfCancellationRequested();
        //more work
    }
    catch (OperationCanceledException)
    {
        throw;
    }
    catch (Exception ex)
    {
        Log.Exception(ex);
        throw;
    }
}

The OperationCanceledException should not be logged as an error but must not be swallowed if the task is to transition into the cancelled state. Any other exceptions do not need to be dealt with beyond the scope of this method.

This always felt a bit clunky, and visual studio by default will break on the throw for OperationCanceledException (though I have ‘break on User-unhandled’ turned off now for OperationCanceledException because of my use of this pattern).

UPDATE: It’s 2021 and C#9 gives me the syntax I always wanted:

public void DoWork(CancellationToken cancelToken)
{
    try
    {
        //do work
        cancelToken.ThrowIfCancellationRequested();
        //more work
    }
    catch (Exception ex) when (ex is not OperationCanceledException)
    {
        Log.Exception(ex);
        throw;
    }
}


Ideally I think I’d like to be able to do something like this:

public void DoWork(CancellationToken cancelToken)
{
    try
    {
        //do work
        cancelToken.ThrowIfCancellationRequested();
        //more work
    }
    catch (Exception ex) exclude (OperationCanceledException)
    {
        Log.Exception(ex);
        throw;
    }
}


i.e. have some sort of exclusion list applied to the catch but without language support that is not currently possible (@eric-lippert: c# vNext feature :)).

Another way would be through a continuation:

public void StartWork()
{
    Task.Factory.StartNew(() => DoWork(cancellationSource.Token), cancellationSource.Token)
        .ContinueWith(t => Log.Exception(t.Exception.InnerException), TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.ExecuteSynchronously);
}

public void DoWork(CancellationToken cancelToken)
{
    //do work
    cancelToken.ThrowIfCancellationRequested();
    //more work
}

but I don’t really like that as the exception technically could have more than a single inner exception and you don’t have as much context while logging the exception as you would in the first example (if I was doing more than just logging it).

I understand this is a bit of a question of style, but wondering if anyone has any better suggestions?

Do I just have to stick with example 1?

  • 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-06-12T00:28:12+00:00Added an answer on June 12, 2026 at 12:28 am

    So, what’s the problem? Just throw away catch (OperationCanceledException) block, and set proper continuations:

    var cts = new CancellationTokenSource();
    var task = Task.Factory.StartNew(() =>
        {
            var i = 0;
            try
            {
                while (true)
                {
                    Thread.Sleep(1000);
    
                    cts.Token.ThrowIfCancellationRequested();
    
                    i++;
    
                    if (i > 5)
                        throw new InvalidOperationException();
                }
            }
            catch
            {
                Console.WriteLine("i = {0}", i);
                throw;
            }
        }, cts.Token);
    
    task.ContinueWith(t => 
            Console.WriteLine("{0} with {1}: {2}", 
                t.Status, 
                t.Exception.InnerExceptions[0].GetType(), 
                t.Exception.InnerExceptions[0].Message
            ), 
            TaskContinuationOptions.OnlyOnFaulted);
    
    task.ContinueWith(t => 
            Console.WriteLine(t.Status), 
            TaskContinuationOptions.OnlyOnCanceled);
    
    Console.ReadLine();
    
    cts.Cancel();
    
    Console.ReadLine();
    

    TPL distinguishes cancellation and fault. Hence, cancellation (i.e. throwing OperationCancelledException within task body) is not a fault.

    The main point: do not handle exceptions within task body without re-throwing them.

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

Sidebar

Related Questions

I'm firing off tasks using an ExecutorService, dispatching tasks that need to be grouped
I'm in the process of writing a library that deals with long-running tasks like
I have this large C++ project that I need to build on a platform
My main program running 8 tasks using Task.Factory.StartNew Each task will request XML format
I’m using a few custom MSBuild tasks that are checked into source control. I
I have a system which breaks a large taks into small tasks using about
I have a Java program performing some large analysis tasks, running through a loop
I'm working on rake tasks for a large .net solution (using the albacore gem)
I am trying to use beanstalk for queuing a large number of periodic tasks
Have some employee segmentation tasks that result in a large number of records (about

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.