首页 > 其他分享 >.net耗时:多线程分段并发执行与单线程异步执行

.net耗时:多线程分段并发执行与单线程异步执行

时间:2023-06-01 11:13:53浏览次数:42  
标签:cancellationToken Task 单线程 queryProgressChanged Action ipAddresses var net 多线程

多线程执行存在线程切换的耗时,可采用单线程异步执行。性能根据实际情况调优。结合上面两种情况:可实现多线程异步执行。目前先看看下面两个例子

1 多线程分段执行设备查找耗时操作

        /// <summary>
        /// 异步查询设备
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="queryProgressChanged"></param>
        /// <param name="currentDevice"></param>
        /// <param name="queryEnd"></param>
        /// <returns></returns>
        public async Task QueryDevicesByScanAsync(CancellationToken cancellationToken, Action<SharingDevice> queryProgressChanged, Action<string> currentDevice, Action queryEnd)
        {
            try
            {
                //放到后台执行,避免卡主界面
                await Task.Run(async () =>
                {
                    //扫描所有局域网内的Ip
                    var ipAddresses = new DeviceScanner().GetScanIpRanges();
                    var threeSection = ipAddresses.Count / 3;
                    var beginTime = Environment.TickCount;

                    var ipAddresses1 = ipAddresses.Take(threeSection).ToList();
                    var ipAddresses2 = ipAddresses.Skip(threeSection).Take(threeSection).ToList();
                    var ipAddresses3 = ipAddresses.Skip(2 * threeSection).Take(ipAddresses.Count - 2 * threeSection).ToList();

                    var query1 = QueryDevicesAsync(ipAddresses1, cancellationToken, queryProgressChanged, currentDevice);
                    var query2 = QueryDevicesAsync(ipAddresses2, cancellationToken, queryProgressChanged, currentDevice);
                    var query3 = QueryDevicesAsync(ipAddresses3, cancellationToken, queryProgressChanged, currentDevice);
                    await Task.WhenAll(query1, query2, query3);
                    Debug.WriteLine($"-------扫描项 {ipAddresses.Count}--------共耗时:{Environment.TickCount - beginTime} -------------------");
                }, cancellationToken);

            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            finally
            {
                queryEnd?.Invoke();
            }
        }
private Task QueryDevicesAsync(List<IPAddress> ipAddresses ,CancellationToken cancellationToken, Action<SharingDevice> queryProgressChanged, Action<string> currentDevice)
        {
            return Task.Run(async () =>
            {
                foreach (var ipAddress in ipAddresses.TakeWhile(ipAddress => !cancellationToken.IsCancellationRequested))
                {
                    //currentDevice?.Invoke(ipAddress.ToString());
                    var isDeviceExist = await IsDeviceExistAsync(ipAddress);
                    if (!isDeviceExist) continue;
                    var hostName = await GetHostNameAsync(ipAddress.ToString());
                    queryProgressChanged?.Invoke(new SharingDevice(ipAddress, hostName));
                }
            }, cancellationToken);
        }

 2 单线程异步查询:不分段

/// <summary>
        /// 异步查询设备
        /// </summary>
        /// <param name="cancellationToken"></param>
        /// <param name="queryProgressChanged"></param>
        /// <param name="currentDevice"></param>
        /// <param name="queryEnd"></param>
        /// <returns></returns>
        public async Task QueryDevicesByScanAsync(CancellationToken cancellationToken, Action<SharingDevice> queryProgressChanged, Action<string> currentDevice, Action queryEnd)
        {
            try
            {
                //放到后台执行,避免卡主界面
                await Task.Run(async () =>
                {
                    //扫描所有局域网内的Ip
                    var ipAddresses = new DeviceScanner().GetScanIpRanges();
                    var beginTime = Environment.TickCount;
                    var query = QueryDevicesAsync(ipAddresses, cancellationToken, queryProgressChanged);
                    await Task.WhenAll(query);
                    Debug.WriteLine($"-------扫描项 {ipAddresses.Count}--------共耗时:{Environment.TickCount - beginTime} -------------------");
                }, cancellationToken);

            }
            catch (Exception e)
            {
                Debug.WriteLine(e);
            }
            finally
            {
                queryEnd?.Invoke();
            }
        }
  private async Task QueryDevicesAsync(List<IPAddress> ipAddresses, CancellationToken cancellationToken, Action<SharingDevice> queryProgressChanged)
        {
            var tasks = new List<Task<bool>>();
            foreach (var ipAddress in ipAddresses)
            {
                cancellationToken.ThrowIfCancellationRequested();
                tasks.Add(IsDeviceExistAsync(ipAddress));
            }
            var results = await Task.WhenAll(tasks);
            for (int i = 0; i < results.Length; i++)
            {
                if (results[i])
                {
                    var hostName = await GetHostNameAsync(ipAddresses[i].ToString());
                    queryProgressChanged?.Invoke(new SharingDevice(ipAddresses[i], hostName));
                }
            }
        }

 

标签:cancellationToken,Task,单线程,queryProgressChanged,Action,ipAddresses,var,net,多线程
From: https://www.cnblogs.com/terryK/p/17448363.html

相关文章

  • windows下通过net user add和powershell添加用户,sysmon仅仅采集到进程,而在windows安全
    执行操作:C:\Windows\system32>netuser/add"jack""fuckoff"命令成功完成。C:\Windows\system32>powershellWindowsPowerShell版权所有(C)MicrosoftCorporation。保留所有权利。尝试新的跨平台PowerShellhttps://aka.ms/pscore6PSC:\Windows\system32&g......
  • Linux 内核 net_proto_family
    staticconststructnet_proto_familyinet_family_ops={.family=PF_INET,.create=inet_create,.owner=THIS_MODULE,};(void)sock_register(&inet_family_ops);/***sock_register-addasocketprotocolhandler*@ops:descriptiono......
  • inetsw table
    /*Theinetswtablecontainseverythingthatinet_createneedsto*buildanewsocket.*/staticstructlist_headinetsw[SOCK_MAX];staticDEFINE_SPINLOCK(inetsw_lock);for(q=inetsw_array;q<&inetsw_array[INETSW_ARRAY_LEN];++q)......
  • 界面控件DevExpress ASP.NET新主题——Office 365暗黑主题的应用
    DevExpressASP.NET WebFormsControls拥有针对Web表单(包括报表)的110+种UI控件,DevExpressASP.NETMVCExtensions是服务器端MVC扩展或客户端控件,由轻量级JavaScript小部件提供支持的70+个高性能DevExpressASP.NETCoreControls,包含功能完善的报表平台。在之前发布的v22.1版......
  • PowerShell实战系列:按需更改.net解决方案中的项目名称
    一、需求  产品在生命周期中可能会更改名称,比如产品从Product1升级为Product2,为了使产品代码与之同步,产品源码项目名称需要改动,通常一个产品由包含很多项目,手动更改有很大的工作量,且未来该工作仍可能重复(产品继续升级,带来改名需求)。  对于大量且重复的工作,编写脚本可有......
  • 使用脚本批量Telnet和Curl测试端口是否连通
    使用脚本批量Telnet测试端口是否连通,使用telnet:telnets.sh:#!/bin/bashcheck_telnet(){forip_portin$(catip_info|grep-v'^#')doCHECK_PORT=$(echo$ip_port|awk-F:'{print$2}')CHECK_IP=$(echo$ip_port|awk-F:'{print$1}')......
  • Spring Boot 定时任务单线程和多线程配置
    第一种:把参数配置到.properties文件中:代码:packagecom.accord.task;importjava.text.SimpleDateFormat;importjava.util.Date;importorg.springframework.scheduling.annotation.Scheduled;importorg.springframework.stereotype.Component;/***从配置文件加载......
  • 开源.NetCore通用工具库Xmtool使用连载 - 发送短信篇
    【Github源码】《上一篇》介绍了Xmtool工具库中的发送邮件类库,今天我们继续为大家介绍其中的发送短信类库。发送短信就像发送邮件一样,在软件系统中使用非常普遍,甚至比发送邮件还要常见,有些甚至是软件标配功能;例如现在的短信验证码登录、通过短信找回密码等等。发送短信需要......
  • yolotv5和resnet152模型预测
    我已经训练完成了yolov5检测和resnet152分类的模型,下面开始对一张图片进行检测分类。首先用yolo算法对猫和狗进行检测,然后将检测到的目标进行裁剪,然后用resnet152对裁剪的图片进行分类。首先我有以下这些训练好的模型 猫狗检测的,猫的分类,狗的分类 我的预测文件my_detect.p......
  • kubernetes(k8s)大白学习02:容器和docker基础、使用、架构学习
    一、什么是容器容器简介简单说:容器(container)就是计算机上的一个沙盒进程,它与计算机上的所有其它进程相隔离。这种隔离是怎么做到的呢?它利用了内核提供的namespace和cgroup这2种技术。这些技术能力在Linux中已经存在了很长时间。而Docker或容器技术致力于将这些功能更......