Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# C、 最大化线程并发性_C#_Multithreading_Concurrency_Task_Maximize - Fatal编程技术网

C# C、 最大化线程并发性

C# C、 最大化线程并发性,c#,multithreading,concurrency,task,maximize,C#,Multithreading,Concurrency,Task,Maximize,在Google和community的帮助下,我能够构建一组很好的方法,允许我异步调用函数。此函数正在测试远程主机属性,因此大部分时间处于空闲状态。出于这个原因,我希望最大化启动的并发线程的数量,这样所有调用都可以在最短的时间内处理 以下是我目前掌握的代码: // Check remote host connectivity public static class CheckRemoteHost { // Private Class members private static

在Google和community的帮助下,我能够构建一组很好的方法,允许我异步调用函数。此函数正在测试远程主机属性,因此大部分时间处于空闲状态。出于这个原因,我希望最大化启动的并发线程的数量,这样所有调用都可以在最短的时间内处理

以下是我目前掌握的代码:

// 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
这就是我想增加/最大化并发启动线程的数量,使之达到每个核心25个线程的数量记住线程作业是99%空闲的

到目前为止,我的线程并发研究已经提出了显式线程和并行方法。但是,它们似乎有相同的缺点,即生成的线程不超过8个


任何帮助都将非常感谢,所以提前非常感谢大家的关注

你的代码让你的生活变得艰难。它有很多不需要的管道,并且共享静态字段,如果在第一次运行Ping时再次调用Ping,则会导致代码失败

你需要把那些东西都扔掉

我建议使用微软的反应式框架——只需使用System.Responsive和add-using System.Responsive.Linq;到您的代码。然后你可以这样做:

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

就这样。这就是您需要的所有代码。它会自动最大限度地利用线程来完成任务。

类似于?任务!=线您可以在一个线程上运行数千个任务。对于异步工作流,您不希望线程数超过核心数-您希望线程数尽可能少。@CoryNelson您不希望线程数超过核心数-陈词滥调。如果我的所有线程都被某个IO磁盘(NW)阻塞,为什么我不在所有内核都空闲时创建一个新的线程呢?@Eser,如我所说,用于异步工作流。您不应该在async中有任何阻塞I/O。@supersausage007在发送新的ping之前,您不必等待上一个ping的应答。这就是为什么在链接的示例中有一个线程专门用于发送它们,还有一个线程专门用于读取回复。谢谢你,你的代码工作得很好,当然比我的解决方案更优雅。对于一些人来说,一个警告可能是需要.NET 4.6或更高版本才能通过GNuGet安装System.Reactive.Linq。就性能而言,我的原始解决方案和您更优雅的解决方案在+4500 IP上都是相同的2300毫秒,ping超时为1500ms-非常有效:我将您的贡献标记为答案,因为您的代码更优雅简洁。
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;
        }
    }
}