簡體   English   中英

在 visual studio 中調用異步 HttpClient.GetAsync() 后調試器停止

[英]Debugger stops after async HttpClient.GetAsync() call in visual studio

我正在嘗試測試以下 http 請求方法

public async Task<HttpContent> Get(string url)
    {
        using (HttpClient client = new HttpClient())
// breakpoint
        using (HttpResponseMessage response = await client.GetAsync(url))
// can't reach anything below this point
        using (HttpContent content = response.Content)
        {
            return content;
        }
    }

但是,調試器似乎跳過了第二條注釋下方的代碼。 我正在使用 Visual Studio 2015 RC,有什么想法嗎? 我也試過檢查任務 window 但什么也沒看到

編輯:找到解決方案

using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace ConsoleTests
{
    class Program
    {
        static void Main(string[] args)
        {
            Program program = new Program();
            var content = program.Get(@"http://www.google.com");
            Console.WriteLine("Program finished");
        }

        public async Task<HttpContent> Get(string url)
        {
            using (HttpClient client = new HttpClient())
            using (HttpResponseMessage response = await client.GetAsync(url).ConfigureAwait(false))
            using (HttpContent content = response.Content)
            {
                return content;
            }
        }
    }
}

事實證明,因為這是一個 C# 控制台應用程序,所以我猜它在主線程結束后結束,因為在添加 Console.ReadLine() 並稍等片刻之后,請求確實返回了。 我猜 C# 會等到我的任務執行並且不會在它之前結束,但我想我錯了。 如果有人能詳細說明為什么會發生這種情況,那就太好了。

Main退出時,程序退出。 取消任何未完成的異步操作並丟棄其結果。

因此,您需要通過阻塞異步操作或其他方法來阻止Main退出(例如,在用戶點擊密鑰之前調用Console.ReadKey來阻止):

static void Main(string[] args)
{
  Program program = new Program();
  var content = program.Get(@"http://www.google.com").Wait();
  Console.WriteLine("Program finished");
}

一種常見的方法是定義一個也執行異常處理的MainAsync

static void Main(string[] args)
{
  MainAsync().Wait();
}

static async Task MainAsync()
{
  try
  {
    Program program = new Program();
    var content = await program.Get(@"http://www.google.com");
    Console.WriteLine("Program finished");
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex);
  }
}

請注意,阻塞異步代碼通常被認為是一個壞主意; 應該完成它的情況很少,並且控制台應用程序的Main方法恰好就是其中之一。

按照 ChatGPT 說明,我遇到了同樣的問題:

string accountId = "12345";
string apiUrl = $"https://api.example.com/GetDashboards/{accountId}";
HttpResponseMessage response = await _httpClient.GetAsync(apiUrl);  // EXPLODES HERE
response.EnsureSuccessStatusCode();

為了修復它,我指定了 BaseUrl:

using var client = new HttpClient();
client.BaseAddress = new Uri(apiUrl);

client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

var urlParameters = "";
var response = await client.GetAsync(urlParameters);
if (response.IsSuccessStatusCode)
{ }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM