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