我有以下调用我的 API 的函数:
private async void applyMe(int id, string data)
{
string url = $"https://localhost:44382/api/isc/getdata?id=" + id + "&data=" + data;
ApiHelper.InitializeClient();
string _apiResult = await APIProcessor.LoadApi(url);
}
API 助手
public static class ApiHelper
{
public static HttpClient ApiClient { get; set; }
public static void InitializeClient()
{
ApiClient = new HttpClient();
ApiClient.DefaultRequestHeaders.Accept.Clear();
ApiClient.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/jason"));
}
}
API处理器
public class APIProcessor
{
public static async Task<string> LoadApi(string url)
{
using (HttpResponseMessage response = await ApiHelper.ApiClient.GetAsync(url))
{
if (response.IsSuccessStatusCode)
{
string _apiResult = await response.Content.ReadAsStringAsync();
return _apiResult;
}
else
{
throw new Exception(response.ReasonPhrase);
}
}
}
}
我想在
foreach
循环中调用我的API,如下所示
using (myEntities _context = new myEntities ())
{
foreach (var item in _context.items.Where(s => s.id >= 1 && s.id <= 500))
{
applyMe(item.id, item.data);
}
}
API 尚未调用,因为
async await
:(
请问我该如何解决这个问题?
使用Task.WhenAll()。它返回一个可等待的任务,当所有其他任务完成时,该等待任务将完成。最后你需要等待而不阻塞线程。请参阅微软文档
using (myEntities _context = new myEntities ())
{
await Task.WhenAll(_context.items
.Where(s => s.id >= 1 && s.id <= 500)
.Select(s => applyMe(item.id, item.data))
);
}
重要! applyMe 应该返回一个任务并且不保持无效。不推荐使用 async void 模式。
为了使这项工作有效,需要进行两个小调整: 第一个任务 is void
private async Task getData(int id, string data)
{
string url = $"https://localhost:44382/api/isc/getdata?id=" + id + "&data=" + data;
ApiHelper.InitializeClient();
string _apiResult = await APIProcessor.LoadApi(url);
}
其次,等待 getData 调用
using (myEntities _context = new myEntities ())
{
foreach (var item in _context.items.Where(s => s.id >= 1 && s.id <= 500))
{
await getData(item.id, item.data);
}
}
您可以使用
IAsyncEnumerable<MyModel>
(docs)
public IAsyncEnumerable<MyModel> GetItems()
{
IQueryable<T> query = this._context.items;
query = query.Where(s => s.id >= 1 && s.id <= 500);
return query.AsAsyncEnumerable();
}
并使用它:
IAsyncEnumerable<MyModel>> items = GetItems();
await foreach (var myModel in items)
{
//Call external api
}