1

Is it thread safe to await 2 tasks (one of the tasks is awaiting the other)?

public async Task<string> Operation1(){}

public async Task<string> Operation2( Task waitMe)
{
    if(DoSomethingSuccess())
        return "EarlySuccess";

    var result = await waitMe;
    return SomeSideEffectThat( result); // I read result
}

void async Task<string> MyMainFunction(){

    Task<string> t1 = Operation1();
    Task<string> t2 = Operation2( t1);

    var result = await Task.WaitAny( new Task<string> { t1, t2});
    if(results.Status == TaskStatus.RanToCompletion)
        return result;

    return "ExceptionOccurred";


}

I'm interested in having the first result from one of the tasks, and eventually the second task to perform side effects. Assume side effects are already thread safe, I'm interested in race conditions over "t2" "t1" and "result" storing.

I need both 2 the operations to run in parallel, that's why I don't continue T1 with T2, it is just that T2 needs T1 to perform some additional operations

UberFace
  • 445
  • 1
  • 4
  • 14
  • 1
    You are doing the async wrong. If Operation1 and Operation2 are already returning a task you don't need to wrap them in an additional tasl via Task.Run. Also use the non-blocking WhenAny instead of the blocking WaitAny. – ckuri Apr 20 '18 at 13:37
  • yes are returning a task, but I need to start it. Creating a task does not run it – UberFace Apr 20 '18 at 13:46
  • Then, is there a way to start the tasks without using Task.Run? both are slow I/O operations – UberFace Apr 20 '18 at 13:47
  • I think you are misunderstanding tasks. The code is running in the moment you call it and the task object contains stuff needed to know when the operation completes. When you call Operation1/Operation2 their task is starting. – ckuri Apr 20 '18 at 13:54
  • Ok thank you I updated the question so that there is no longer Task.Run, I was not aware that "async" methods are started automatically (ever before awaiting) – UberFace Apr 20 '18 at 14:02
  • is that worked for you ? – Pranay Rana Apr 23 '18 at 11:22
  • yes, anyway since i'm on aspnet I have to use task run otherwise tasks get canceled when http call end – UberFace Apr 23 '18 at 12:43

1 Answers1

0

why dont you just use ContinueWith

  Task.Factory.StartNew(() => negate(5))
         //you can go with another task here  
        .ContinueWith(antecendent => negate(antecendent.Result))        ;
Pranay Rana
  • 175,020
  • 35
  • 237
  • 263
  • 1
    Task.Run is preferred over Task.Factory.StartNew. Also there is no point to wrap your code in a task, if you call Wait anyway. – ckuri Apr 20 '18 at 13:40
  • @ckuri - https://blogs.msdn.microsoft.com/pfxteam/2011/10/24/task-run-vs-task-factory-startnew/ – Pranay Rana Apr 20 '18 at 13:46
  • Your link does not state anything about a race condition for Task.Run which wouldn't occur for Task.Factory.StartNew. In fact it does say that you can use Task.Run anytime you call the default Task.Factory.StartNew. – ckuri Apr 20 '18 at 14:00
  • @ckuri - read this , you get information https://stackoverflow.com/a/38423507/314488 (yeah i am wrong about race condition but its all about preference , i like start new as there are number of parameter supported by it – Pranay Rana Apr 21 '18 at 18:50