6

I am trying to add timeout to this code, but because I am new to this, I can't figure out,

Task.Factory.StartNew(() =>
{
     Aspose.Words.Document doc = new Aspose.Words.Document(inputFileName);
     doc.Save(Path.ChangeExtension(inputFileName, ".pdf"));
});

Also I want main thread to wait here until it timeout for 5 minutes or completes.

Edit

Or can I use cancellation token with this, if yes then how :( ?

Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
Mathematics
  • 7,314
  • 25
  • 77
  • 152

1 Answers1

7

You can create a new Task using Task.Delay and use Task.WhenAny:

Task delayedTask = Task.Delay(TimeSpan.FromMinutes(5));
Task workerTask = Task.Factory.StartNew(() =>
{
     Aspose.Words.Document doc = new Aspose.Words.Document(inputFileName);
     doc.Save(Path.ChangeExtension(inputFileName, ".pdf"));
});

if (await Task.WhenAny(delayedTask, workerTask) == delayedTask)
{
   // We got here because the delay task finished before the workertask.
}
else
{
   // We got here because the worker task finished before the delay.
}

You can use Microsoft.Bcl.Async to add async-await abilities to .NET 4.0

Edit:

As you're using VS2010, you can use Task.Factory.ContinueWheAny instead:

Task.Factory.ContinueWhenAny(new[] { delayedTask, workerTask }, task =>
{
    if (task == delayedTask)
    {
        // We got here if the delay task finished before the workertask.
    }
    else
    {
        // We got here if the worker task finished before the delay.
    }
});

Edit 2:

Since Task.Delay isn't available in .NET 4.0, you can create it yourself using an Extension Method:

public static class TaskExtensions
{
    public static Task Delay(this Task task, TimeSpan timeSpan)
    {
        var tcs = new TaskCompletionSource<bool>();
        System.Timers.Timer timer = new System.Timers.Timer();
        timer.Elapsed += (obj, args) =>
        {
            tcs.TrySetResult(true);
        };
        timer.Interval = timeSpan.Milliseconds;
        timer.AutoReset = false;
        timer.Start();
        return tcs.Task;
    } 
}
Yuval Itzchakov
  • 146,575
  • 32
  • 257
  • 321
  • Thanks for quick answer, but do i need to add any assembly as I am receiving these errors, http://prntscr.com/5k07ly – Mathematics Dec 23 '14 at 08:12
  • Yes, you need to add the assemblies via `NuGet`. I added a link in the post – Yuval Itzchakov Dec 23 '14 at 08:15
  • I like this answer. @YuvalItzchakov does WhenAny cancel the other task execution after first one completes? What is the correct way to afterwards find out which Task was completed? – supertopi Dec 23 '14 at 08:20
  • 1
    No, it doesn't cancel it. But if you pass a `CancellationToken` to it, you can cancel it yourself. As for your second question, i've edited my code. – Yuval Itzchakov Dec 23 '14 at 08:21
  • Okay! I would assume the first thing we want to do after first Task completes is to cancel the second running Task :) – supertopi Dec 23 '14 at 08:27
  • You *could* cancel the task if needed. Simply pass the `CancellationToken` and invoke it from inside the `if-else`. Note the `Task` being cancelled will have to monitor the `CancellationToken` in use `ThrowIfCancellationRequested`. – Yuval Itzchakov Dec 23 '14 at 08:30
  • thanks, but shame I am using Visual Studio 2010 and there is no way i can add nuget package to it :( – Mathematics Dec 23 '14 at 08:35
  • it says Task has no definition for delay - http://prntscr.com/5k0f76 – Mathematics Dec 23 '14 at 08:47
  • @CustomizedName See my second edit. – Yuval Itzchakov Dec 23 '14 at 08:56
  • Delay method still taking 1 parameter but expecting 2 :( sorry me new to this – Mathematics Dec 23 '14 at 11:12
  • @CustomizedName Make sure you have this `this` modifier inside the methods signature declaration: `public static Task Delay(this Task task, TimeSpan timeSpan)` – Yuval Itzchakov Dec 23 '14 at 11:16