Generic callbacks from C# Tasks

Viewed 519

What is the recommended way to call generic callbacks from an async Task? For example, progress, exception handling and completion (but could be other states).

The following code shows one way to implement it, but feels like there should be a cleaner way to handle this. (FWIW I've seen plenty of examples using ContinueWith as a completion callback, but this doesn't really deal with other cases like progress and exception handling).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Testcode
{
    class TestApp
    {
        public static void Main()
        {
            AsyncCallbackTest test = new AsyncCallbackTest();
            test.RunTest();
        }
    }

    interface ICallback
    {
        void onProgress(String status);
        void onCompleted();
        void onFaulted(Exception e);
    }

    class AsyncCallbackTest : ICallback
    {

        public void RunTest()
        {
            //run task in background
            Task task = new Task(new Action<Object>(ExampleTask), this);
            task.Start();

            //do something else here
            //...

            //wait for task completion
            task.Wait();
        }

        public void onProgress(string status)
        {
            Console.Out.WriteLine(status);
        }

        public void onCompleted()
        {
            Console.Out.WriteLine("COMPLETED");
        }

        public void onFaulted(Exception e)
        {
            Console.Out.WriteLine("EXCEPTION: " + e.Message);
        }

        private void ExampleTask(object ocb)
        {
            ICallback callback = ocb as ICallback;

            //do some work
            try
            {
                DoSomething(callback);
            }
            catch (Exception e)
            {
                //how to pass exceptions/errors?
                callback.onFaulted(e);
            }
        }

        //example long-running task
        private void DoSomething(ICallback callback)
        {
            callback.onProgress("Starting");
            Thread.Sleep(5000);
            callback.onProgress("Step 1 complete");
            Thread.Sleep(5000);
            callback.onProgress("Step 2 complete");
            Thread.Sleep(5000);
            callback.onCompleted();
        }
    }
}
2 Answers
Related