我在下面的文章中遇到了关于何时何地使用ConfigureAwait(false)
的文章,但无法获得答案。
您不需要ConfigureAwait(false),但仍在库中使用它,和UI应用。 (例如Xamarin,WinForms等)
https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html
This link说相反的答案
Best practice to call ConfigureAwait for all server-side code
When correctly use Task.Run and when just async-await
我的问题:
方案1:以下代码正在作为后台服务运行。
我的问题:无论何时像下面的A和B一样使用ConfigureAwait(false)
,是否都需要await
:
[Service(Name = "com.MainApplicationService", Label = "Main Application Service", Exported = false)]
public class MainApplicationService : Android.App.Service
{
public override IBinder OnBind(Intent intent)
{
return null;
}
[return: GeneratedEnum]
public override StartCommandResult OnStartCommand(Intent intent, [GeneratedEnum] StartCommandFlags flags, int startId)
{
await InitAsync().ConfigureAwait(false); //line A
Task.Run(async () => await InitAsync().ConfigureAwait(false)); //line B
return StartCommandResult.Sticky;
}
}
方案2:下面的代码作为UI线程而不是后台服务运行
相同的问题:每次使用等待都需要ConfigureAwait(false)
,如下面的C和D:
public class StartupActivity : Android.App.Activity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
await InitAsync().ConfigureAwait(false); //line C
Task.Run(async () => await InitAsync().ConfigureAwait(false)); //line D
Finish();
}
}
Xamarin Android版本8,我认为它是.net标准。
https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md
也许是一种不受欢迎的观点,但是现在,即使在图书馆中,我也不使用ConfigureAwait(false)
,请参阅:
Revisiting Task.ConfigureAwait(continueOnCapturedContext: false)
IMO,if使用基于Task.ConfigureAwait(continueOnCapturedContext: false)
的API的代码关注当前的同步上下文以及它如何影响该API的行为(死锁,冗余上下文切换等),它可以显式包装用Task
调用API或使用上述链接中的Task.Run
之类的东西:
TaskExt.WithNoContext
尽管在大多数情况下,尤其是对于UI应用程序(可伸缩性不成问题),可以不加await Task.Run(() => InitAsync());
// or
await TaskExt.WithNoContext(() => InitAsync());
或Task.Run
即可将其保持原样:
ConfigureAwait
[这将使您有机会发现并研究潜在的死锁,然后再尝试通过await InitAsync();
或ConfigureAwait(false)
减轻它们。
因此,在相同的同步上下文中继续操作,并非不是一个好主意,尤其是在将未处理的异常发布到当前同步上下文的Task.Run
方法内部时,请参阅async void
。>>