简体   繁体   English

在 c# 的 foreach 循环中调用 API

[英]Calling API inside foreach loop in c#

I have the following function that call my API我有以下 function 调用我的 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 Helper 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"));
    }
}

APIProcessor 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);
            }
        }
    }
}

I want to call my API inside foreach loop as below我想在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);
      }
 }

The API not calling yet because of async await :( Please how can I solve this issue?由于async await ,API 尚未调用 :( 请问我该如何解决这个问题?

Thanks in advance提前致谢

Use Task.WhenAll().使用 Task.WhenAll()。 It returns an awaitable that will get completed when all other tasks are finished.它返回一个等待所有其他任务完成时完成的任务。 In the end you need to wait without blocking the thread.最后你需要等待而不阻塞线程。 see microsoft doc微软文档

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))
                      );
}

Important!重要的! The applyMe should return a Task and not remain void. applyMe 应该返回一个 Task 并且不会保持无效。 The async void pattern is not recommended.不推荐使用 async void 模式。

You could use IAsyncEnumerable<MyModel> ( docs )您可以使用IAsyncEnumerable<MyModel>文档

public IAsyncEnumerable<MyModel> GetItems()
{
    IQueryable<T> query = this._context.items;

    query = query.Where(s => s.id >= 1 && s.id <= 500);

    return query.AsAsyncEnumerable();
}

And use it with:并将其用于:

IAsyncEnumerable<MyModel>> items = GetItems();
await foreach (var myModel in items)
{
    //Call external api         
}                

Two small adjustments to make this work: First Task iso void进行这项工作的两个小调整:第一个任务 iso 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);     
}

and second, await the getData call其次,等待 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);
      }
 }

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM