C# 申请书填写在“申请表”中;等待状态“;而HttpRequest操作

C# 申请书填写在“申请表”中;等待状态“;而HttpRequest操作,c#,asynchronous,request,httprequest,async-await,C#,Asynchronous,Request,Httprequest,Async Await,我正在对返回xml内容的Url执行HttpRequest。因此,我尝试发出一个异步请求,但在这个请求过程中,应用程序被停止(暂停),并且它似乎无法得到响应(浏览器中的url工作正常,它返回我所期望的结果) 这是我的密码: public static async Task<String> getResponse(String url) { HttpClient httpClient = new HttpClient(); HttpResponseMessage requ

我正在对返回xml内容的Url执行HttpRequest。因此,我尝试发出一个异步请求,但在这个请求过程中,应用程序被停止(暂停),并且它似乎无法得到响应(浏览器中的url工作正常,它返回我所期望的结果)

这是我的密码:

public static async Task<String> getResponse(String url)
{
    HttpClient httpClient = new HttpClient();
    HttpResponseMessage request = await httpClient.GetAsync(url);
    String stream = await request.Content.ReadAsStringAsync();
    return stream;
}

有人能帮我吗?

这里发生的是僵局。在没有太多信息的情况下,我看到您在调用时阻塞了异步操作

string response = UtilityClass.getResponse(requestUrl).Result
发生的情况是,当您在
getResponse
内部
wait
时,生成的
TaskAwaitable
会捕获您的任务,以便将延续封送回调用它的相同上下文。但是,当它尝试将工作bacl封送到捕获的上下文时,它无法执行,因为
Result
正在阻塞线程。这就是为什么你应该这么做。这可以通过使用来修复,它告诉
TaskAwaitable
不要封送延续,只需在调用它的当前线程上执行:

public static async Task<String> getResponse(String url)
{
    HttpClient httpClient = new HttpClient();
    HttpResponseMessage request = await httpClient.GetAsync(url).ConfigureAwait(false);
    String stream = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
    return stream;
}
这需要您向调用方法添加
async
关键字。如果不能,那么同步http请求可能是更好的解决方案

编辑

引用@EricLippert的评论,使其更容易理解:

这里要理解的关键是
result=task.result表示在结果可用之前不做任何其他事情,
result=wait task
;表示在结果可用之前执行其他操作。两者都将
任务
转换为字符串,但一个阻塞,另一个不阻塞

有许多很好的帖子解释了async/await的基本原理:


  • 你说你没有得到回应是什么意思?回答是空的吗?它抛出了异常还是什么?您得到的状态码是什么?我添加的“.Result”是从getResponse方法中获取字符串结果,因为它返回一个任务,我想要获取字符串。。对不起,也许我有点困惑。我没有找到同步http请求的示例:/only asynchronous…。当调用
    任务的
    结果
    属性时,它会像使用同步请求时一样阻塞。添加
    ConfigureAwait(false)
    正如我在示例中所显示的那样是的,谢谢,我添加了ConfigureAwait(false)并且代码可以工作,但是我如何才能在没有.Result的情况下获得响应流呢?我调用getResponse方法使其工作并返回任务,如何从返回的任务中获取字符串?如果
    等待getResponse
    ,则字符串将从
    任务中展开。如果没有,请使用Result属性(由于使用了ConfigureAwait,它将阻塞但不会死锁)@Pame1692:这里要理解的关键是
    Result=task.Result表示在结果可用之前不做任何其他事情,
    result=wait task意味着在结果可用之前做其他事情。两者都将
    任务
    转换为
    字符串
    ,但一个阻塞,另一个不阻塞。
    public static async Task<String> getResponse(String url)
    {
        HttpClient httpClient = new HttpClient();
        HttpResponseMessage request = await httpClient.GetAsync(url).ConfigureAwait(false);
        String stream = await request.Content.ReadAsStringAsync().ConfigureAwait(false);
        return stream;
    }
    
    string response = await UtilityClass.getResponse(requestUrl)