要使用Xamarin Android ver 8,.net Standard运行和不运行带有服务和活动的ConfigureAwait(false)

问题描述 投票:2回答:1

我在下面的文章中遇到了关于何时何地使用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

c# xamarin xamarin.android async-await task-parallel-library
1个回答
0
投票

也许是一种不受欢迎的观点,但是现在,即使在图书馆中,我也不使用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。>>

© www.soinside.com 2019 - 2024. All rights reserved.