我尝试连接到API并从中获取数据。但是我没有在HttpResponseMessage代码行之后获得任何东西.if(response.IsSuccessStatusCode)永远不会运行。我已经尝试了一切,但还没有。请帮忙。这是我的代码。
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;
}
}
}
调用Ajax方法 函数TotalTestMonthly(){
$.ajax({
url: '../JKLLAPI/MakeRequest',
type: 'POST',
dataType: 'json',
cache: false,
async: false,
data: {},
success: function (data) {
if (data.Success == true) {
}
}
});
}
答案 0 :(得分:2)
既然你已经说过“永远不会”运行IsSuccessStatusCode行,即使在超时后也没有,我猜你发生了死锁情况。
正如我上面评论的那样,Stephen Cleary有一个非常好的article来描述这个问题。他还写了MSDN article。
总结(如果链接的文章消失了):
someTask.Wait();
上阻止注意:根据Stephen的MSDN文章,控制台应用程序没有此问题,因为它们使用TaskScheduler。 VS'单元测试任务运行器确实有这个问题,这就是我学习它的方法。
那么,你能做什么?
如果您正在从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(...)
然后您可以使用标准等待,并按照您的预期处理上下文。
在异步方法中,您可以调用ConfigureAwait:
await Task.Delay(1000).ConfigureAwait(continueOnCapturedContext: false);
// or, simply:
await Task.Delay(1000).ConfigureAwait(false);
这会导致该方法在线程池上下文中执行其余的异步方法,从而避免死锁。
如果由于某种原因你无法处理或包装异步方法,那么你也可以使用Task.Run
:
// You can also use Task<string>.Run(...), for example
var task = Task.Run(async () => await someAsyncMethod());
task.Wait();
使用Task.Run将在线程池上下文中执行异步方法,从而避免死锁。
我的解释实际上并没有正确的主题,所以我强烈建议阅读我上面链接的文章。我只是想确保我的答案包含一些有价值的内容,如果链接永远消失: - )
注意执行异步的正确方法是异步完全向下(即从按钮单击到最深的异步调用)。不应在异步方法中使用。
我已经用我自己的快速示例来演示这些技巧:
// 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";
}