在visual studio中调用async HttpClient.GetAsync()后调试器停止
本文关键字:调试器 GetAsync HttpClient studio visual 调用 async | 更新日期: 2023-09-27 18:01:33
我正在尝试测试以下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,有什么想法吗?我也试着检查任务窗口,但什么也没看到
编辑:找到解决方案
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)
{ }