在C#中的foreach循环内调用API

问题描述 投票:0回答:3

我有以下调用我的 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
:( 请问我该如何解决这个问题?

c# asynchronous dotnet-httpclient
3个回答
2
投票

使用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 模式。


0
投票

为了使这项工作有效,需要进行两个小调整: 第一个任务 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);
      }
 }

0
投票

您可以使用

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         
}                
© www.soinside.com 2019 - 2024. All rights reserved.