1

I'm new to c# async await mechanism. I read some articles about async all the way (http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html). I have an example below, could you please let me know if the first Initialize method will cause dead lock and why? Thank you in advance.

public class Test {

    public  async  Task DoSomeWorkAsync() {
      await DoSomeWork1Async(); 
    }

    // This method is mixed with Wait and async await, will this cause lead lock?
    public void Initialize() {
      Task.Run(() => DoSomeWorkAsync()).Wait();
    }

    // This method is following async all the way
    public async Task InitializeAsync()  {
      await DoSomeWorkAsync();
    }

}

// Update: Here is the context where two Initialize methods are called
public class TestForm : Form {
  // Load Form UI
  public async void OnLoad() {
    var test = new Test();
    test.Initialize();
    await test.InitializeAsync();
  }
}
i3arnon
  • 113,022
  • 33
  • 324
  • 344
macio.Jun
  • 9,647
  • 1
  • 45
  • 41
  • 2
    It depends on context where you are using it. – Hamlet Hakobyan Aug 24 '15 at 17:57
  • In the `Initialize()` method, I would simply do `DoSomeWorkAsync().Wait()`. Using `Task.Run()` will start a new thread and call DoSomeWorkAsync() synchronously. – Philippe Paré Aug 24 '15 at 18:00
  • thanks guys I added context where they are being used. – macio.Jun Aug 24 '15 at 18:02
  • @PhilippeParé: thx Philippe, but will DoSomeWorkAsync().Wait() cause dead lock? I assume async-await all the way down means once you use asyn-await, you can't mix Wait(). Please Correct me if I'm wrong. – macio.Jun Aug 24 '15 at 18:06
  • You can certainly use Wait() on a Task, it will simply be executed synchronously. If by "dead lock" you mean a UI thread block, then yes, Wait() will block the UI thread but only for the execution of the method. – Philippe Paré Aug 24 '15 at 18:11
  • 1
    @PhilippeParé no. It will deadlock as in it will get stuck forever. – i3arnon Aug 24 '15 at 18:11

1 Answers1

6

No, this will not deadlock because you're blocking on a task that's being executed by a ThreadPool thread with no SynchronizationContext. Since it isn't running on the UI thread there's nothing stopping that task from completing and so there's no deadlock.

If this was your code, it will have deadlocked:

public void Initialize()
{
    DoSomeWorkAsync().Wait();
}

This is still not a good reason to block though, you should use async-await all they way up.

i3arnon
  • 113,022
  • 33
  • 324
  • 344
  • @i3amon: thx i3amon. The reason I wanna use Initialize() over InitializeAsync() is because class TestForm has a lock object, which prevent OnLoad method being called concurrently, which looks like this: lock(lockObj) {Initialize(); } However await InitializeAsync(); could not be called within lock statement. – macio.Jun Aug 24 '15 at 18:23
  • 1
    @macio.Jun then use an [AsyncLock](http://stackoverflow.com/a/21011273/885318) instead – i3arnon Aug 24 '15 at 18:24
  • @macio.Jun sure.. any time. – i3arnon Aug 24 '15 at 18:39
  • @i3amon, sorry I have one more unclear point. Is there a difference between Initialize method above and public void Initialize() {Task.Run(async() => await DoSomeWorkAsync()).Wait();} ? – macio.Jun Aug 24 '15 at 19:56
  • 1
    @macio.Jun not really, the `async` and `await` are redundant. – i3arnon Aug 24 '15 at 20:19