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

文章展示了两种设备查询方法:多线程分段执行和单线程异步查询。多线程方案将IP地址分为三部分并行处理,而单线程方案则一次性处理所有IP。这两种方法都考虑了取消操作和进度更新,并通过Task.Run和Task.WhenAll来实现异步。文章旨在探讨不同策略对性能的影响。
摘要由CSDN通过智能技术生成

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值