gpt4 book ai didi

C# Async/Await 从不在 MVC4 中响应

转载 作者:太空狗 更新时间:2023-10-29 23:39:37 30 4
gpt4 key购买 nike

我已经为 async/await 苦苦挣扎了一个星期。一些背景:下面的代码是 MVC4 网站项目的一部分。该网站有大量的 API 调用发生。目标是让这些 API 调用并行发生而不是同步发生,以提高站点响应能力。现在所有的 API 调用都互相阻塞。因此,如果一个页面需要 4 次调用……加载时间更长。

我已经为所有 API 调用的同步和异步版本构建了单独的方法。我遇到的问题是 await 从不响应。我认为这与 this question 有关.但是,我真的不确定如何解决它。我已经尝试了 ConfigureAwait(false),但这对我没有帮助。

代码如下:

Controller 中的初始调用如下所示:

BaseData bdata = API.GetBaseData().Result;

我很想在这里使用 await,但如果没有 AsyncController,那不是一个选项,由于需要请求/响应访问,我们无法使用它。其他方法在 API 类中:

internal static async Task<BaseData> GetBaseData() {
var catTask = GetParentCategoriesAsync();
var yearTask = GetYearsAsync();

await Task.WhenAll(new Task[] { catTask, yearTask });

var bdata = new BaseData {
years = await yearTask,
cats = await catTask
};
return bdata;
}

internal static async Task<List<APICategory>> GetParentCategoriesAsync() {
try {
WebClient wc = new WebClient();
wc.Proxy = null;

string url = getAPIPath();
url += "GetFullParentCategories";
url += "?dataType=JSON";

Uri targeturi = new Uri(url);
List<APICategory> cats = new List<APICategory>();

var cat_json = await wc.DownloadStringTaskAsync(targeturi);
cats = JsonConvert.DeserializeObject<List<APICategory>>(cat_json);

return cats;
} catch (Exception) {
return new List<APICategory>();
}
}

internal static async Task<List<double>> GetYearsAsync() {
WebClient wc = new WebClient();
wc.Proxy = null;
Uri targeturi = new Uri(getAPIPath() + "getyear?dataType=JSON");
var year_json = await wc.DownloadStringTaskAsync(targeturi);
List<double> years = JsonConvert.DeserializeObject<List<double>>(year_json);
return years;
}

调用这些方法时,我可以在 GetYearsAsync() 和 GetParentCategoriesAsync() 中放置断点。一切都会触发,直到 await wc.DownloadStringTaskAsync(targeturi) 命令。这就是停止的地方。

我已将 ConfigureAwait(continueOnCapturedContext: false) 添加到所有任务中,但这没有帮助。我假设问题是线程不在同一上下文中。但是,我不确定。但是,我确定我做错了什么。我只是不确定是什么。要么是那样,要么我只是想做一些 .NET MVC4 无法完成的事情。任何想法都将不胜感激。

最佳答案

问题实际上是由于 WebClient 引起的,它总是同步回请求上下文(由于 Result 调用而被阻止).

您可以改用 HttpClient,并结合 ConfigureAwait(false):

internal static async Task<BaseData> GetBaseDataAsync() {
var catTask = GetParentCategoriesAsync();
var yearTask = GetYearsAsync();

await Task.WhenAll(catTask, yearTask).ConfigureAwait(false);

var bdata = new BaseData {
years = await yearTask,
cats = await catTask
};
return bdata;
}

internal static async Task<List<APICategory>> GetParentCategoriesAsync() {
try {
var client = new HttpClient();

string url = getAPIPath();
url += "GetFullParentCategories";
url += "?dataType=JSON";

Uri targeturi = new Uri(url);
List<APICategory> cats = new List<APICategory>();

var cat_json = await client.GetStringAsync(targeturi).ConfigureAwait(false);
cats = JsonConvert.DeserializeObject<List<APICategory>>(cat_json);

return cats;
} catch (Exception) {
return new List<APICategory>();
}
}

internal static async Task<List<double>> GetYearsAsync() {
var client = new HttpClient();
Uri targeturi = new Uri(getAPIPath() + "getyear?dataType=JSON");
var year_json = await client.GetStringAsync(targeturi).ConfigureAwait(false);
List<double> years = JsonConvert.DeserializeObject<List<double>>(year_json);
return years;
}

这应该使您能够这样调用它:

BaseData bdata = API.GetBaseDataAsync().Result;

但是,我强烈建议您这样调用它:

BaseData bdata = await API.GetBaseDataAsync();

你会发现 await 之前和之后的代码都可以很好地访问请求和响应上下文。

关于C# Async/Await 从不在 MVC4 中响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16989498/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com