Search code examples
c#multithreadingtaskcontinuewith

Is there a way to use TaskContinuationOptions like a finally


Is there a way to use TaskContinuationOptions like a finally?

Here is my code

        ShowLoading();
        Task.Factory.StartNew((Action)(() =>
        {
            _broker.SetDrugDataFromAPI(newDrug);

        })).ContinueWith(x => 
        {
            lock (this)
            {
                //Do Something to UI
            }
        }, _uiScheduler).ContinueWith(x =>
        {
            //Do Somehting after change UI
        }).ContinueWith(x =>
        {
            HideLoading();
        }, TaskContinuationOptions.OnlyOnFaulted);

Here is my question

I wanted to use last ContinueWith like a finally. So, I changed my last ContinueWith phrase like this

        }).ContinueWith(x =>
        {
            HideLoading();
        }, TaskContinuationOptions.OnlyOnRanToCompletion | 
           TaskContinuationOptions.OnlyOnFaulted);

I thought it be used when the last task is complete or fault.

But It throws a error.

I hope there is a good way to solve my problem.

thank you for reading my question.


Solution

  • If you don't specify a TaskContinuationOptions then it will run in all states - whether the Task is faulted (Exception), cancelled, or completed successfully.

    For example:

    using System;
    using System.Threading;
    using System.Threading.Tasks;
    
    public class Program
    {
        public static async Task Main()
        {
            using (var cts = new CancellationTokenSource())
            {
                var task = Task.CompletedTask
                .ContinueWith(t => Console.WriteLine("Run after completed"))
                .ContinueWith(t => throw new Exception("Blow up"))
                .ContinueWith(t => Console.WriteLine("Run after exception"))
                .ContinueWith(t => cts.Cancel())
                .ContinueWith(t => Console.WriteLine("This will never be hit because we have been cancelled"), cts.Token)
                .ContinueWith(t => Console.WriteLine("Run after cancelled."));
    
                await task;
            }
        }
    }
    

    This program produces the following output:

    Run after completed
    Run after exception
    Run after cancelled.