2015-08-24 407 views
1

我是新來的c#異步等待機制。我讀了一些關於異步的文章(http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html)。我在下面有一個例子,如果第一個Initialize方法會導致死鎖,請告訴我爲什麼?先謝謝你。異步一直等待異步

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(); 
    } 
} 
+2

這取決於您使用它的環境。 –

+0

在'Initialize()'方法中,我會簡單地執行'DoSomeWorkAsync()。Wait()'。使用'Task.Run()'將啓動一個新線程並同步調用DoSomeWorkAsync()。 –

+0

感謝球員我添加了他們正在使用的上下文。 –

回答

6

不,這不會發生死鎖,因爲您阻止,就會向正由ThreadPool線程沒有SynchronizationContext執行的任務。因爲它沒有在UI線程上運行,所以沒有任何東西可以阻止這個任務完成,所以沒有死鎖。

如果這是你的代碼,它會陷入僵局:

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

這仍然不是一個很好的理由,雖然阻擋,你應該使用異步等待所有他們一路上揚。

+0

@ i3amon:thx i3amon。我想在InitializeAsync()上使用Initialize()的原因是,類TestForm有一個鎖對象,它阻止同時調用OnLoad方法,它看起來像這樣:lock(lockObj){Initialize(); }然而,等待InitializeAsync();無法在鎖定語句中調用。 –

+1

@ macio.Jun然後使用[AsyncLock](http://stackoverflow.com/a/21011273/885318)而不是 – i3arnon

+1

非常感謝您的教學i3amon。 –