C#,最大化线程并发 [英] C#, Maximize Thread Concurrency
问题描述
在Google和社区的帮助下,我能够建立一套不错的方法,使我可以异步调用一个函数.此功能正在测试远程主机属性,因此大多数时间处于空闲状态.因此,我想最大化启动的并发线程数,以便可以在最短的时间内处理所有调用.
With the help of Google and community, I was able to build a nice set of methods allowing me to asynchronously call a function. This function is testing remote host properties, so it is idling most of the time. For this reason I would like to maximize the number of concurrent threads launched such that all calls can be processed in the minimum amount of time.
这是我到目前为止的代码:
Here is the Code I have so far:
// Check remote host connectivity
public static class CheckRemoteHost
{
// Private Class members
private static bool AllDone = false;
private static object lockObj = new object();
private static List<string> IPs;
// Wrapper: manage async method <Ping>
public static List<string> Ping(HashSet<string> IP_Ports, int TimeoutInMS = 100)
{// async worker method: check remote host via <Ping>
// Locals
IPs = new List<string>();
// Perform remote host check
AllDone = false;
Ping_check(IP_Ports, TimeoutInMS);
while (!AllDone) { CommonLib.Utils.ApplicationWait(10, 10); }
// Finish
return IPs;
}
private static async void Ping_check(HashSet<string> IP_Ports, int timeout)
{
// Locals
var tasks = new List<Task>();
// Build task-set for parallel Ping checks
foreach (string host in IP_Ports)
{
var task = PingAndUpdateAsync(host, timeout);
tasks.Add(task);
}
// Start execution queue
await Task.WhenAll(tasks).ContinueWith(t =>
{
AllDone = true;
});
}
private static async Task PingAndUpdateAsync(string ip, int timeout)
{
// Locals
System.Net.NetworkInformation.Ping ping;
System.Net.NetworkInformation.PingReply reply;
try
{
ping = new System.Net.NetworkInformation.Ping();
reply = await ping.SendPingAsync(ip, timeout);
if(reply.Status == System.Net.NetworkInformation.IPStatus.Success)
{
lock (lockObj)
{
IPs.Add(ip);
}
}
}
catch
{
// do nothing
}
}
}// end public static class CheckRemoteHost
此代码已进行了广泛的测试,该代码似乎稳定且可靠地报告了活动主机.话虽如此,我知道它一次只产生8个线程(=我的测试机器上逻辑核心的数量).
This code is tested quite extensively, and the code seems stable and reliably report live hosts. Having said that, I know that it only spawns 8 threads at a time (= number of logical core on my test machine).
代码的关键部分是这样:
The key portion of the code is this:
// Start execution queue
await Task.WhenAll(tasks).ContinueWith(t =>
{
AllDone = true;
});
在这里我想将并发启动的线程数增加/最大化到每个内核25个左右(请记住线程作业是99%空闲的).
This is where I would like to increase/ maximize the number of concurrently launched threads to something like 25 per core (remember the thread job is 99% idle).
到目前为止,我的线程并发研究提出了显式线程和Parallel.For方法.但是,它们似乎具有产生不超过8个线程的相同缺点.
So far, my thread concurrency research has brought up the explicit thread and Parallel.For approaches. However, these seem to have the same shortcoming of spawning no more than 8 threads.
任何帮助将不胜感激,所以在此先非常感谢大家的光临!
Any help would be very much appreciated, so thank you very much in advance everyone for looking!
推荐答案
您正在用自己的代码使生活变得艰难.有很多不必要的工作,而且您正在共享静态字段,如果在第一个运行时再次调用Ping
,则会导致代码失败.
You're making your life hard with the code you have. It's got a lot of plumbing that isn't needed and you're sharing static fields that would cause your code to fail if you called Ping
a second time while the first one is running.
您需要摆脱所有这些东西.
You need to get rid of all of that stuff.
我建议使用Microsoft的Reactive Framework-仅使用NuGet"System.Reactive",然后将using System.Reactive.Linq;
添加到您的代码中.然后,您可以执行以下操作:
I'd suggest using Microsoft's Reactive Framework - just NuGet "System.Reactive" and add using System.Reactive.Linq;
to your code. Then you can do this:
public static class CheckRemoteHost
{
public static IList<string> Ping(HashSet<string> IP_Ports, int TimeoutInMS = 100)
{
var query =
from host in IP_Ports.ToObservable()
from status in Observable.FromAsync(() => PingAsync(host, TimeoutInMS))
where status
select host;
return query.ToList().Wait();
}
private static async Task<bool> PingAsync(string ip, int timeout)
{
try
{
var ping = new System.Net.NetworkInformation.Ping();
var reply = await ping.SendPingAsync(ip, timeout);
return reply.Status == System.Net.NetworkInformation.IPStatus.Success;
}
catch
{
return false;
}
}
}
就是这样.这就是您需要的所有代码.它会自动最大限度地利用线程来完成工作.
That's it. That's all of the code you need. It's automatically maximising the thread use to get the job done.
这篇关于C#,最大化线程并发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!