C# Task 使用 WhenAll 请求远程分页接口

这篇具有很好参考价值的文章主要介绍了C# Task 使用 WhenAll 请求远程分页接口。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

首先WhenAll 是什么?

-所有提供的任务已完成时,创建将完成的任务-
-Creates a task that will complete when all of the supplied tasks have completed-

Task.WhenAll() 方法是 C# 中用于等待多个任务(Task)完成的一种方式。它不会控制并发数量,而是等待所有传递给它的任务都完成后才会继续执行下一步操作。这意味着一旦所有任务都完成,无论这些任务是如何并发执行的,Task.WhenAll() 方法才会返回。

具体用法还是去看官方文档,这是最好的教程: .NET Core 官方教程-Task.WhenAll()

请求远程分页接口并返回实体数据

我这里写的通用模板,用的Task.WhenAll 的重载方法: WhenAll<TResult>(IEnumerable<Task<TResult>> tasks)

我这里为了控制并发数量,使用 SemaphoreSlim 来控制同时执行的任务数量。

SemaphoreSlim 用于控制并发数量,确保同时只有最大数量的任务在执行。每个任务在开始执行时获取信号量,完成后释放信号量,这样可以确保同时执行的任务数量不会超过预定的最大并发数。

请注意,这只是一种控制并发数量的方式之一。

以下就是我的示例:

public async Task<Result<IEnumerable<T>>> RequestRemoteDatas<T>(string token, TableDataQueryParams param, int maxConcurrentTasks = -1)
{
    try
    {
        var content = new StringContent(JsonConvert.SerializeObject(param),
                                        Encoding.UTF8, Application.Json);
        var client = _httpClientFactory.CreateClient();
        client.DefaultRequestHeaders.Add("X-Access-Token", token);
        //client.Timeout = TimeSpan.FromSeconds(30);
        string url = AppSettings.TableDataHost + AppSettings.TableDataQueryUri;

        // 发送post请求
        HttpResponseMessage response = await client.PostAsync(url, content);
        var responseContent = await response.Content.ReadAsStringAsync();
        var result = JsonConvert.DeserializeObject<QueryApiResult>(responseContent);
        if (!result.success || result.code != 200)
        {
            return Result.BadRequest<IEnumerable<T>>(result.message); 
        }
        var records = JsonConvert.DeserializeObject<PlatformManagerDto<T>>(result.result.ToString());
        if (records == null)
        {
            return Result.NotFound<IEnumerable<T>>();
        }
        var dtos = new List<T>();

        if (records.Records.Any())
        {
            dtos.AddRange(records.Records);
        }

        if(records.Pages > 1)
        {
            var tasks = new List<Task<Result<IEnumerable<T>>>>();

            SemaphoreSlim? semaphore = null;
            if (maxConcurrentTasks >= 0)
            {
                //Maximum number of concurrent writes
                semaphore = new SemaphoreSlim(maxConcurrentTasks);
            }

            for (int i = 2; i <= records.Pages; i++)
            {
                int index = i;
                tasks.Add(Task.Run(async () =>
                                   {
                                       param.pageNo = index;
                                       var content1 = new StringContent(JsonConvert.SerializeObject(param),
                                                                        Encoding.UTF8, Application.Json);

                                       if (semaphore != null)
                                       {
                                           semaphore.Wait();
                                       }

                                       try
                                       {
                                           // Perform task operations
                                           // 发送post请求
                                           HttpResponseMessage response1 = await client.PostAsync(url, content1);
                                           var responseContent1 = await response1.Content.ReadAsStringAsync();
                                           var result1 = JsonConvert.DeserializeObject<QueryApiResult>(responseContent1);
                                           if (!result1.success || result1.code != 200)
                                           {
                                               return Result.BadRequest<IEnumerable<T>>(result1.message);
                                           }
                                           var records_next = JsonConvert.DeserializeObject<PlatformManagerDto<T>>(result1.result.ToString());
                                           if (records_next == null)
                                           {
                                               return Result.NotFound<IEnumerable<T>>();
                                           }
                                           return Result.Success(records_next.Records);
                                       }
                                       catch (Exception ex)
                                       {
                                           return Result.BadRequest<IEnumerable<T>>(ex.Message);
                                       }
                                       finally
                                       {
                                           if (semaphore != null)
                                           {
                                               semaphore.Release();
                                           }
                                       }                                
                                   }
                                  ));
            }

            var continuation = Task.WhenAll(tasks);
            continuation.Wait();
            if (continuation.Status == TaskStatus.RanToCompletion)
            {
                foreach (var result1 in continuation.Result)
                {
                    if (result1.Code != 200)
                    {
                        return Result.BadRequest<IEnumerable<T>>(result1.Msg);
                    }
                    dtos.AddRange(result1.Data);
                }
            }
        }
        return Result.Success(dtos.AsEnumerable());
    }
    catch (Exception ex) 
    {
        return Result.BadRequest<IEnumerable<T>>(ex.Message);
    }
}

总之,这篇博客希望能够为您提供有价值的信息,并激发您的思考。

或者,您有更好的建议欢迎在评论区留言。

-感谢您花时间阅读这篇博客-文章来源地址https://www.toymoban.com/news/detail-640203.html

到了这里,关于C# Task 使用 WhenAll 请求远程分页接口的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C#通过请求url调用接口返回数据

     方法描述:通过请求url,调用对方系统的接口,拿到数据并返回; 方法参数:访问系统的url地址 url请求参数:searchDate(当前请求的年月:2023-7),需进行url编码

    2024年02月15日
    浏览(50)
  • C# Http 请求接口 Get / Post

    目录 一、概述 二、创建 Web API  三、HttpRequestHelper 三、测试 结束 get 和 post 请求,最早被用来做浏览器与服务器之间交互HTML和表单的通讯协议,后来又被广泛的扩充到接口格式的定义上,到目前为止,get / post 请求依然应用在各大网站中,比如在用户登录时,调用 get / post 

    2024年02月11日
    浏览(50)
  • C#中请求HTTP接口api的方法

    大家好,我是雄雄,欢迎关注微信公众号: 雄雄的小课堂 现在是:2023年2月15日22:14:30 搞代码的 陈戌源 都知道,哦,不好意思,是程序员,那个 陈戌源 好像是个“清官”…我们都知道,在 java 中调用 api 接口很简单,网上也有好多封装好的依赖,我们在项目中直接添加依赖

    2024年02月06日
    浏览(50)
  • Unity C# 之 Task、async和 await 结合使用的一些情况处理

    目录 Unity C# 之 Task、async和 await  结合使用的一些情况处理 一、简单介绍 二、把 async 函数,通过变化转为一般的函数 三、在 async 函数中,切换到主线程,并等待主线程执行完毕,继续 async 中的代码 Unity 在使用 Task 结合 async (await) 的时候,偶尔会遇到一些特殊情况,需要

    2024年01月22日
    浏览(46)
  • Unity中的异步编程【5】——在Unity中使用 C#原生的异步(Task,await,async) - System.Threading.Tasks

    1、System.Threading.Tasks中的Task是.Net原生的异步和多线程包。 2、UniTask(Cysharp.Threading.Tasks)是仿照.Net原生的Task,await,async开发的一个包,该包专门服务于Unity,所以取名UnityTask,简称UniTask。 3、既然有Task了,为啥还要搞一个UniTask (1)Task可以用在PC和Android上,但是在WebGL上则会

    2023年04月17日
    浏览(51)
  • C# webservice 接收json数据 接口返回 远程服务器返回错误: (500) 内部服务器错误

    C# post 调用webservice 服务端接口,会返回上面那个错误,8成是发送的数据和接口不符合造成的。有2种情况 第一种情况如下:如果类型是默认request.ContentType = \\\"application/x-www-form-urlencoded\\\";这个类型 那么你发送数据和被调用接口参数名如果不对,则会报下图这个错 我发送的参数名

    2024年02月13日
    浏览(64)
  • Winform中使用HttpClient(设置最大超时响应时间)调用接口并做业务处理时界面卡住,使用async Task await异步任务编程优化

    Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类: Winform中怎样使用HttpClient调用http的get和post接口并将接口返回json数据解析为实体类_winform请求http接口_霸道流氓气质的博客-CSDN博客 参考前面使用HttpClient调用http的get和post接口的小示例, 需要定

    2024年02月02日
    浏览(57)
  • Unity C# 之 使用 HttpWebRequest 基础知识/HttpWebRequest 进行异步Post 网络访问/数据流形式获取数据(Task/async/await)的代码简单实现

    目录 Unity C# 之 使用 HttpWebRequest 基础知识/HttpWebRequest 进行异步Post 网络访问/数据流形式获取数据(Task/async/await)的代码简单实现 一、简单介绍 二、实现原理 三、注意事项 四、效果预览 五、关键代码 附录 : HttpWebRequest 的一些基础知识 1、HttpWebRequest 常用属性 2、HttpWebRequest 

    2024年02月05日
    浏览(60)
  • c#入门-Task创建线程

    在c#中,有线程类。激活线程对象就可以实现多线程。 不过,这是在代码角度来说的。你可以在代码中创建一万个线程。 但实际上你的cpu没有一万个逻辑处理器来真正同时执行这一万个线程。 所以我们称创建一万个线程为创建一万个并发——我们希望同时执行一万个线程,

    2024年02月01日
    浏览(43)
  • C#基础--线程之Task

    Task 是.NetFramework3.0出现的,Task里面的线程是来自于线程池 1. 开启一个线程 Task 构造函数 传入一个无参数的 Action 委托作为参数 Run() 静态方法 TaskFactory 工厂 Task.Delay 延迟执行 Task.Delay 出现于4.5版本 Thread.Sleep() 是阻塞的,而 Delay 是非阻塞的;如果Sleep 和Delay 平级,则会因Sle

    2024年02月16日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包