3

I have a (possibly) lengthy operation a to which I want to impose a limit time constraint t (in milliseconds). If operation a takes less than t milliseconds to complete then I return the answer from operation a; otherwise I want to abort the operation and return a proper error code stating that the time limit constraint was exceeded.

How can I accomplish this in C#? If you have other ideas that are language agnostic feel free to share?

Jorge Ferreira
  • 96,051
  • 25
  • 122
  • 132
  • How did you end up solving this problem? I have a similar situation - The operation is time-sensitive as well as time-constrained - and so I prefer to not spin up additional threads with abort handling, not poll CancellationToken, not rely on Task as it might exhaust the thread pool. Also checking lapsed time after every few steps on the current thread would seems like a bad idea. But so far leaning towards https://stackoverflow.com/a/22078975/3142593 – HappyTown Feb 09 '21 at 05:02

4 Answers4

5

Best is to wrap it in a Task<T> or Task and use Wait.

Look here.

Task t = new Task(DoStuff());
t.Wait(1000);
Aliostad
  • 80,612
  • 21
  • 160
  • 208
  • 2
    But the task keeps running on the background. I saw there is a `CancellationTokenSource` from which we can take a `CancellationToken` and pass it to the `Task` ctor. But this implies pooling on `CancellatoinToken.IsCancellationRequest` to finish the task. But good point. – Jorge Ferreira Apr 14 '11 at 08:34
2

You could kick off two threads: One for Operation "a", and another with a timer.

If the timer thread finishes, it checks whether the Operation "a" thread has finished. If not, abort the (still running) thread and return your timeout error code.

If Operation "a" finishes before the timer thread does, just kill the timer thread before returning your result.

tobias86
  • 4,979
  • 1
  • 21
  • 30
  • 1
    this was my initial idea. The big problem here is how to safely "abort" the running thread. Also an extra thread seems unnecessary, use the thread that received the request as the timer thread and spawn only the worker thread. – Jorge Ferreira Apr 14 '11 at 08:33
0

Use BeginInvoke on the method, than after some time check IAsyncResult.IsCompleted. If it is completed, get the result with EndInvoke.

Sjoerd
  • 74,049
  • 16
  • 131
  • 175
0

There is some material on this already see Implement C# Generic Timeout

The general theme is to have an asynchronous thread (delegate, task etc) to keep an eye on time. Be very careful about Thread.Abort(), you should leave the task running if you can, or use some kind of clean cancellation.

Community
  • 1
  • 1
trickdev
  • 627
  • 1
  • 7
  • 14
  • They all circle around `Thread.Abort`. Will read it trough to see if there are any valuable points. – Jorge Ferreira Apr 14 '11 at 08:35
  • The point I am trying to make is, you can use the patterns from some of those answers (read all of the comments, one of them causes deadlocks) but you don't need to Thread.Abort() - just leave the process running or use cancellation. – trickdev Apr 14 '11 at 13:05