2015-12-31 104 views
11

我想找到我的项目之一的最佳实践。这是一个典型的带有UI的WPF应用程序,它显示项目列表,并且有一个返回结果的数据服务。异步等待vs GetAwaiter()。GetResult()和回调

我们正在异步调用该服务,以便不阻止用户界面。我们已经在我们面前的两个选项:

  1. 使用异步等待关键字 这需要标记所有的按钮的方法异步单击所有服务层的方式(在客户端类,使HTTP调用服务器)和其中的任何方法。这种方法能正常工作等,然后到处传播异步的问题

  2. 使用awaiter和回调 在这种方法中,UI客户端调用业务层和传送回调到服务层,服务层包装了HTTP调用服务器,并使用GetAwaiter()。GetResult(),当http调用完成时,调用UI客户端传递的回调函数。在这种情况下,没有方法必须标记为异步,但不确定使用GetAwaiter()。GetAwaiter()。GetResult() );

我只是试图找出这是一个更好的办法,如果有一些问题有两种方法,我应该知道的

+1

我敢肯定,第二种方法偶尔会导致死锁。我知道,因为我在使用Windows Universal进行开发时遇到了类似的情况。 – Felype

+0

也有例外的问题。我知道一个完整的异步实现,最后得到'AggregateException',但我不知道'GetAwaiter'方法中的异常会发生什么。 – Eris

+0

@Eris当您等待时,您不会收到'AggregateException'。你会得到内在的异常。 'GetResult'也是一样。 – i3arnon

回答

16

您应该使用asyncawait关键字一路攀升,或者你不应该使用异步。

你的第二个选项并不是非同步的。它正在调用异步操作并与task.GetAwaiter().GetResult()同步地对其进行阻止。 除了非常复杂之外,它不是异步的,可能导致死锁。

+0

你有更多关于为什么会导致死锁的背景信息?我也经历过这种情况,但我正在寻找一些更深入的信息,说明为什么会发生这种情况或这是如何工作的。 –

+2

@FrederikGheysels http://blog.stephencleary.com/2012/07/dont-block-on-async-code.html – i3arnon

+0

听起来像很棒的建议,除非我从Azure Active Directory(TokenCache)中获取此API需要同步操作。直到读取缓存后才能从“BeforeAccessNotification”返回,并且在写入缓存之前无法从“AfterAccessNotification”返回。当你被迫进入同步API并需要访问文件时,你有什么建议? –