第三方使用的 Azure 函数 REST API - 是不是需要使用 ConfigureAwait(false)?

Posted

技术标签:

【中文标题】第三方使用的 Azure 函数 REST API - 是不是需要使用 ConfigureAwait(false)?【英文标题】:Azure function REST API used by third parties - does it need to use ConfigureAwait(false)?第三方使用的 Azure 函数 REST API - 是否需要使用 ConfigureAwait(false)? 【发布时间】:2020-01-07 13:07:30 【问题描述】:

我的任务是在 .NET Core 2.1+ 中使用 Azure Functions 创建 REST API,但我担心死锁。我们将有一个现场方使用 javascript 框架调用 POST 请求的 API,以及其他发出 POST 请求并以其他方式使用它的场外方。 Stephen Cleary 在这里说 - Is .GetAwaiter().GetResult(); safe for general use? - Azure 函数总是在没有上下文的情况下运行代码。 Stephen 在这里说 - https://blog.stephencleary.com/2017/03/aspnetcore-synchronization-context.html - ASP.NET Core 应用程序不使用与旧版 ASP.NET 相同的 SynchronizationContext。他说阻塞异步代码不会死锁,因为它运行在线程池线程上,所以没有理由使用 ConfigureAwait(false)。但是,如果您正在编写在非 ASP.NET Core 应用程序中重用的核心库,则应该使用 ConfigureAwait(false)。由于 Azure 基于函数的 REST API 没有上下文并且是独立的,是否需要使用 ConfigureAwait(false) 来防止死锁?

编辑:我的代码如下所示:

private readonly ILogger<AzureMockFunctions> _logger;

    public AzureMockFunctions(ILogger<AzureMockFunctions> logger)
    
        _logger = logger;
    

[FunctionName("Function")]
    public Task<ActionResult<Teacher>> Run(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = "null")] HttpRequest request)
    
        try
        
            _logger.LogInformation("C# HTTP trigger function processed a request.");

            using (StreamReader reader = new StreamReader(request.Body, Encoding.UTF8))
            
                string requestBody = reader.ReadToEndAsync().GetAwaiter().GetResult();
                Teacher data = JsonConvert.DeserializeObject<Teacher>(requestBody);

                if (data == null)
                    throw new Exception("request body is empty");
            

            Teacher teacher = new Teacher
            
                prop1 = "some string",
                prop2 = "1",
                prop3 = "some other string"
            ;                

            return Teacher;
        
        catch (Exception ex)
        
            _logger.LogError($"An error occurred: ex");

            return new BadRequestObjectResult(new
            
                message = "An error occurred: " + ex.Message
            );
        
    

public class Teacher

    public string prop1 get; set; 
    public string prop2 get; set; 
    public string prop3 get; set; 

【问题讨论】:

分享你的请求码sn-p。 ASP.NET Core 没有SynchronizationContext。如果你在 ASP.NET Core 上,不管你是否使用ConfigureAwait(false) Stephen Cleary 在他的博客(第二个链接)上说——“我仍然建议你在核心库中使用它——任何可以在其他应用程序中重用的东西。如果你的库中有代码也可以在 UI 应用程序、旧版 ASP.NET 应用程序或任何其他可能存在上下文的地方运行,那么您仍应在该库中使用 ConfigureAwait(false)。”这是我的问题 - 由于我的基于 .NET Core 的 Azure 函数/REST API 被其他可能使用上下文的应用程序使用,我是否需要将 ConfigureAwait(false) 添加到我的异步代码中? 【参考方案1】:

关于斯蒂芬·克利里的告诫:

我仍然建议您在核心库中使用它——任何可以在其他应用程序中重用的东西。如果您的库中的代码也可能在 UI 应用程序或旧版 ASP.NET 应用程序或其他任何可能存在上下文的地方运行,那么您仍应在该库中使用 ConfigureAwait(false)。

当他谈到“库”时,Stephen Cleary 是在谈论 DLL。当您通过 REST API 将自己与调用者分开时,根据此定义,您的代码不符合“库”的条件。如果您确定您的代码只会在 .NET Core 上下文中使用,则可以安全地省略对 .ContinueAwait(false) 的调用。

【讨论】:

这正是我说独立时的想法 - 感谢您的确认!

以上是关于第三方使用的 Azure 函数 REST API - 是不是需要使用 ConfigureAwait(false)?的主要内容,如果未能解决你的问题,请参考以下文章

使用 Rest Api 查询 Azure 表存储

使用Azure REST API创建虚拟机

使用Azure设备配置服务的rest API注册设备?

C# 使用 REST API 连接到 Azure 媒体服务帐户

如何使用 REST API 创建 Azure 搜索索引器

使用 Azure 通知中心 REST API 读取频道的所有注册