【问题标题】:Azure .NET Core Appservice locks up sending 502.3 because of async callsAzure .NET Core App Service 由于异步调用而锁定发送 502.3
【发布时间】:2019-12-14 17:17:49
【问题描述】:

我在 Azure 应用服务中运行的 .NET Core 2.X 应用中运行此方法。我有一个远程服务器,我们使用此方法从 Angular 网站中的按钮按下调用。调用远程设备。

Angular 按钮 --> Azure 中的 .NET Core 应用服务 --> 另一个应用服务 --> 互联网\蜂窝连接设备。我们等待设备的响应返回状态码。

如果我快速向此方法发送命令 [2 或 3 次],它会导致应用服务停止响应,直到我重新启动它。我读了这个post 并添加了[, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)]

但是我仍然可以冻结整个应用程序并需要重新启动才能快速向此方法发送命令。

private async void SetEndPointValueAsync(string stunnelUrl, string username, string password)
{
            try
            {
                //set the user name and password
                var httpClientHandler = new HttpClientHandler()
                {
                    Credentials = new NetworkCredential(username, password)
                };
                using (var client = new HttpClient(httpClientHandler))
                {
                    using (var response = await client.GetAsync(stunnelUrl**, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false)**)
                    {
                        if (response.IsSuccessStatusCode)
                        {
                            LogInfo(typeof(IntegrationService), stunnelUrl, LogAction.EndpointUpdate);
                        }
                        else
                        {
                            //request failed.
                            LogWarning(typeof(IntegrationService), stunnelUrl, LogAction.DeviceRequest);
                        }
                        //using (var content = response.Content)
                        //{
                        //    //do here your changes when required
                        //}
                    }
                }
            }
            catch (Exception e)
            {
                LogErrorDetailed(e, typeof(IntegrationService), stunnelUrl, LogAction.DeviceRequest);
            }
}

【问题讨论】:

  • async void 始终是一个危险信号,除非它是一个事件处理程序。你有什么理由不返回Task?你怎么称呼这个方法?我们能看到那个代码吗?

标签: c# asp.net-mvc .net-core async-await


【解决方案1】:

一般来说,您不希望创建如此多的 HttpClient 实例,因为您会失去它提供的管理带来的很多好处。

你可以通过只拥有一个实例来减少一些开销,就像这样......

private readonly HttpClient _client;

public ClassConstructor(HttpClient client)
{
    _client = client ?? new HttpClient();       
}

然后你可以改变你的方法看起来像这样......

private async Task SetEndPointValueAsync(Uri stunnelUri, string username, string password)
{
    if (stunnelUri == null) throw new ArgumentNullException(nameof(stunnelUri));
    if (String.IsNullOrEmpty(username)) throw new ArgumentNullException(nameof(username));
    if (String.IsNullOrEmpty(password)) throw new ArgumentNullException(nameof(password));

    byte[] byteArray = Encoding.ASCII.GetBytes($"{username}:{password}");
    string scheme = "Basic";
    string parameter = Convert.ToBase64String(byteArray);

    HttpRequestMessage request = new HttpRequestMessage();
    request.Method = HttpMethod.Post;
    request.RequestUri = stunnelUri;
    request.Headers.Authorization = new AuthenticationHeaderValue(scheme, parameter);
    try
    {
        HttpResponseMessage response = await _client.SendAsync(request);

        // This will throw an HttpRequestException if there is a failure above
        response.EnsureSuccessStatusCode();

        // do your stuff here...
        // { ... }

    }
    catch (HttpRequestException)
    {
        // { log your connection / bad request issue. }
    }
    catch (Exception) 
    {
        // I don't recommend this, but since you had it...
        // { handle all other exceptions }
    }
}

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-08
    相关资源
    最近更新 更多