2015-08-24 362 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。 –