简体   繁体   English

HttpResponseMessage不返回任何响应?

[英]HttpResponseMessage Not Returning any response?

Im trying connect to a API and get the data from it. 我正在尝试连接到API并从中获取数据。 But Im not getting Anything after HttpResponseMessage code line.if (response.IsSuccessStatusCode) never runs. 但是我在HttpResponseMessage代码行之后没有得到任何信息.if(response.IsSuccessStatusCode)从未运行。 I have tried everything, but nothing yet. 我已经尝试了一切,但还没有尝试。 please help. 请帮忙。 This is my code. 这是我的代码。

using System;
using Newtonsoft;
using System.Net.Http.Headers; 
using System.Text; 
using System.Net.Http; 
using System.Web; 
using System.Collections.Generic;
using Newtonsoft.Json;
using System.Xml;
using System.Web.Mvc;
using System.Threading.Tasks;


namespace JKLLAppMobile.API
{
public class JKLLAPI : Controller
{
    public async Task<List<JasonData>> MakeRequest()
    {
        List<JasonData> HanaData = new List<JasonData>();

        var client = new HttpClient();
        var queryString = HttpUtility.ParseQueryString(string.Empty);
        queryString["format"] = "json";
        queryString["filter"] = "BDATU eq '20170421' and BWLVS eq '609'";
        var uri = "https://jkhapimdev.azure-api.net/api/beta/v2/bound/?" + queryString;

        HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, uri);
        request.Headers.Authorization = new AuthenticationHeaderValue("Ocp-Apim-Subscription-Key", "{Token-Key}");
        HttpResponseMessage response = await client.SendAsync(request);

        if (response.IsSuccessStatusCode)
        {
            var responseString = await response.Content.ReadAsStringAsync();
            string json_data = JsonConvert.SerializeObject(responseString); 


        }

        return HanaData;
    }
}

} }

Calling Ajax Method function TotalTestMonthly() { 调用Ajax方法函数TotalTestMonthly(){

    $.ajax({
        url: '../JKLLAPI/MakeRequest',
        type: 'POST',
        dataType: 'json',
        cache: false,
        async: false,
        data: {},
        success: function (data) { 
            if (data.Success == true) {

            } 
        }
    }); 
}

Since you have said it "never" runs the IsSuccessStatusCode line, not even for after a timeout, I'd guess that you have a deadlock situation happening. 既然您说过它“从不”运行IsSuccessStatusCode行,即使超时后也不会运行,我想您可能会遇到僵局。

As I commented above, Stephen Cleary has a really good article which describes the problem. 正如我在上面评论的那样,Stephen Cleary有一篇非常好的文章描述了这个问题。 He has also penned an MSDN article . 他还撰写了MSDN文章

To summarise (in case the linked articles ever disappear): 总结一下(如果链接的文章消失了):

  • When you make an async call the current SynchronizationContext (or, if it's null, the TaskScheduler) is captured as a kind of return point for the async call. 当您进行异步调用时,当前的SynchronizationContext(如果为null,则为TaskScheduler)将被捕获为异步调用的一种返回点。
  • GUI and ASP.NET applications use SynchronizationContext. GUI和ASP.NET应用程序使用SynchronizationContext。 This only allows one block of synchronous code to run at once. 这仅允许一次运行同步代码块。
  • Once your async task has completed, it will try to return to the SynchronizationContext, which, if you're starting from a non-async position, will be blocked on someTask.Wait(); 异步任务完成后,它将尝试返回到SynchronizationContext,如果您从非异步位置开始,它将在someTask.Wait();上被阻止someTask.Wait();
  • Once you reach this point, you have a situation where your synchronous code is waiting for your asynchronous code, and your asynchronous code is waiting to return to your synchronous code, causing a deadlock. 一旦达到这一点,您就会遇到一种情况,您的同步代码正在等待您的异步代码,而您的异步代码正在等待返回到您的同步代码,从而导致死锁。

Note: According to Stephen's MSDN article, console applications do not have this issue because they use the TaskScheduler. 注意:根据Stephen的MSDN文章,控制台应用程序没有此问题,因为它们使用TaskScheduler。 VS' Unit Test task runner does have this issue, which is how I learned of it. VS的单元测试任务运行程序确实存在此问题,这是我从中学到的。


So, what can you do? 所以,你可以做什么?

If you're running async from a GUI context, eg a button click, you should change your button click handler to an async method: 如果从GUI上下文运行异步,例如按钮单击,则应将按钮单击处理程序更改为异步方法:

// you can't change void to Task because of the type the delegate expects,
// but this is the correct way to do this.
public async void OnClicked(...)

You can then use the standard await, and the context is handled as you would expect. 然后,您可以使用标准的await,然后按预期方式处理上下文。

In your async methods you can call ConfigureAwait: 在您的异步方法中,您可以调用ConfigureAwait:

await Task.Delay(1000).ConfigureAwait(continueOnCapturedContext: false);
// or, simply:
await Task.Delay(1000).ConfigureAwait(false);

This causes the method to execute the rest of the async method in the Thread Pool context, which averts the deadlock. 这将导致该方法在线程池上下文中执行其余的异步方法,从而避免了死锁。

If for some reason you can't handle, or wrap, the async method, then you can also use Task.Run : 如果由于某种原因您无法处理或包装async方法,则也可以使用Task.Run

// You can also use Task<string>.Run(...), for example
var task = Task.Run(async () => await someAsyncMethod());
task.Wait();

Using Task.Run will execute the async method within the Thread Pool context, and thus avoid the deadlock. 使用Task.Run将在线程池上下文中执行async方法,从而避免死锁。

My explanation really doesn't do the topic justice, so I highly recommend reading the articles I linked above. 我的解释确实没有使主题公正,因此,我强烈建议您阅读上面链接的文章。 I just wanted to make sure my answer contained some valuable content if the links were to ever disappear :-) 我只是想确保我的答案包含一些有价值的内容,如果这些链接要消失的话:-)

Note The correct way to do async is async all the way down (ie from the button click to the deepest async call). 注意进行异步的正确方法是一直向下同步(即从按钮单击到最深的异步调用)。 Task.Run shouldn't be used within an async method. Task.Run不应异步方法中使用。


I've put together my own quick example to demonstrate these techniques: 我整理了自己的快速示例来演示这些技术:

// Deadlocks
public void button2_Click(object sender, EventArgs e)
{
    var task = GetNews();
    task.Wait();
    MessageBox.Show(task.Result);
}

// Doesn't deadlock
public async void button3_Click(object sender, EventArgs e)
{
    var result = await GetNews();
    MessageBox.Show(result);
}

// Doesn't deadlock
public void button4_Click(object sender, EventArgs e)
{
    var task = GetNews(false);
    task.Wait();
    MessageBox.Show(task.Result);
}

// Doesn't deadlock
public void button5_Click(object sender, EventArgs e)
{
    var task = Task<string>.Run(async () => await GetNews());
    task.Wait();
    MessageBox.Show(task.Result);
}

// The boolean option is just so that I don't have to write two example methods :)
// You obviously don't have to pass this as a parameter, and can just directly call ConfigureAwait
public async Task<string> GetNews(bool continueOnCapturedContext = true)
{
    await Task.Delay(100).ConfigureAwait(continueOnCapturedContext: continueOnCapturedContext);
    return "hello";
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 返回带有批处理响应的HttpResponseMessage - Returning an HttpResponseMessage with a batch response 返回HttpResponseMessage并配置Application Insights时,WebAPI响应永远不会完成 - WebAPI Response never completes when returning HttpResponseMessage and Application Insights is configured 返回HTTP 403.7 HTTPResponseMessage - Returning an HTTP 403.7 HTTPResponseMessage GetAsync:不返回HttpResponseMessage - GetAsync : not returning HttpResponseMessage 将自定义 HttpResponseMessage 作为 IActionResult 返回 - Returning custom HttpResponseMessage as IActionResult HttpResponseMessage没有响应 - No response from HttpResponseMessage 当响应为 HttpStatusCode.NoContent 时,有什么方法可以获取 HttpResponseMessage.Content 正文? - Is there any way how to get HttpResponseMessage.Content body when response is HttpStatusCode.NoContent? .Net Core在HttpResponseMessage中返回一个int - .Net Core returning an int in HttpResponseMessage 返回HttpResponseMessage时的WebAPI Gzip - WebAPI Gzip when returning HttpResponseMessage 返回HttpResponseMessage的控制器未正确设置内容类型 - Controller returning HttpResponseMessage not setting content type correctly
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM