1

I need to execute many methods at the same time and the result of all, concatenate them in a single list. In the following example, I wait 3 seconds for each method, but in one of them I added a sleep (10 seconds) to check the result and it is not the expected one. The method never cancels and waits for those 10 seconds. What is the problem? Thank you!

var result = await Task.Run(() => Load<MyCustomClass>(OneMethod(), OtherMethod())); private List<T> OneMethod() { return new List<T>(); } private List<T> OtherMethod() { Thread.Sleep(10000); return new List<T>(); } private async Task<List<T>> Load<T>(params List<T>[] taskList) { try { return (await Task.WhenAll(taskList.Select(x => Task.Run(() => x, new CancellationTokenSource(3000).Token)))).SelectMany(x => x).ToList(); } catch (Exception currentException) { //BLA BLA BLA } return new List<T>(); } 
5
  • 2
    You are using Thread.Sleep(), when you should be using the Task based equivalent, Task.Delay() Commented Sep 2, 2018 at 3:56
  • 2
    You can remove the first await Task.Run(() => Load.. and write await Load.. Commented Sep 2, 2018 at 7:14
  • @AndrewWilliamson Hi, thanks for the help. But I have the same result. I added a 30 seconds delay, but it keeps happening. Commented Sep 2, 2018 at 15:38
  • @Max Hi, thanks for the help. But I have the same result. Commented Sep 2, 2018 at 15:38
  • Why Task.Run? Commented Sep 3, 2018 at 7:29

1 Answer 1

2

You must pass the CancellationToken to the methods and check if cancellationToken is requested or directly raise an exception.

var t = new CancellationTokenSource(3000).Token var result = await Task.Run(() => Load<MyCustomClass>(OneMethod(t), OtherMethod(t))); private List<T> OneMethod(CancellationToken t) { token.ThrowIfCancellationRequested(); return new List<T>(); } private List<T> OtherMethod(CancellationToken t) { Thread.Sleep(10000); token.ThrowIfCancellationRequested(); // or you can check if cancellation is requested // if (token.IsCancellationRequested) ... return new List<T>(); } private async Task<List<T>> Load<T>(params List<T>[] taskList) { try { return (await Task.WhenAll(taskList.Select(x => Task.Run(() => x)))).SelectMany(x => x).ToList(); } catch (Exception currentException) { //BLA BLA BLA } return new List<T>(); } 

See this question

Sign up to request clarification or add additional context in comments.

4 Comments

Max, OtherMethod will still block for 10 seconds, even though the cancellation is requested after 3 seconds. You could make the method asynchronous, and change it to await Task.Delay(10000, t). That way, it will throw a cancellation exception after 3 seconds as expected
@pere57 It's true, it still does not work, could you give an example of how to make it work? Thank you!
Why Task.Run?
I changed the code as little as possible in order to better clarify the concept. Obviously the delay does not exist in the real code and the check if the token is expired must be done in other parts.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.