Home > Software engineering >  Get return value of method from TaskCompletionSource
Get return value of method from TaskCompletionSource

Time:05-20

I have a method RenderReport which generates a PDF file (byte[]). This can sometimes hang indefinitely. It should take no more than 15 seconds to complete when successful. Hence, I'm using a TaskCompletionSource to be able to limit the execution time and throw a TimeoutException if it exceeds the timeout.

However, what I can't determine is: how do you provide the byte[] file returned by RenderReport to the SetResult in the following code? longRunningTask.Wait returns a boolean and not the file so where do you get the file from?

I don't want to use longRunningTask.Result as that can enter image description here

So it's just one approach, but is this helpful at all?

using System;
using System.Threading;
using System.Threading.Tasks;

namespace task_completion
{
    class Program
    {
        static void Main(string[] args)
        {
            runAsync();
            Console.ReadKey();            
        }

        static async void runAsync()
        {
            // Normal
            await longRunningByteGetter(1000, new CancellationTokenSource(2000).Token)                
                .ContinueWith((Task<byte[]> t)=> 
                {
                    switch (t.Status)
                    {
                        case TaskStatus.RanToCompletion:
                            var bytesReturned = t.Result;
                            Console.WriteLine($"Received {bytesReturned.Length} bytes");
                            break;
                        default:
                            Console.WriteLine(nameof(TimeoutException));
                            break;
                    }
                });

            // TimeOut
            await longRunningByteGetter(3000, new CancellationTokenSource(2000).Token)
                .ContinueWith((Task<byte[]> t) =>
                {
                    switch (t.Status)
                    {
                        case TaskStatus.RanToCompletion:
                            var bytesReturned = t.Result;
                            Console.WriteLine($"Received {bytesReturned.Length} bytes");
                            break;
                        default:
                            Console.WriteLine(nameof(TimeoutException));
                            break;
                    }
                });
        }

        async static Task<Byte[]> longRunningByteGetter(int delay, CancellationToken token)
        {
            await Task.Delay(delay, token); // This is a mock of your file retrieval
            return new byte[100];
        }
    }
}
  • Related