C# 调用静态函数的并行任务

C# 调用静态函数的并行任务,c#,task,C#,Task,我对并行任务有异议 我的代码 名称空间设备 { 使用System.Linq; 使用System.Collections.Generic; 使用System.Threading.Tasks; 使用制度; /*设备模式*/ 公共类设备 { 公共字符串IP{get;set;} 公共字符串名称{get;set;} 公共字符串MAC{get;set;} } /*入门级*/ 班级计划 { 静态异步void Main(字符串[]args) { 列表任务=新列表(); 对于(int i=2;i==0;i--

我对并行任务有异议 我的代码

名称空间设备
{  
使用System.Linq;
使用System.Collections.Generic;
使用System.Threading.Tasks;
使用制度;
/*设备模式*/
公共类设备
{
公共字符串IP{get;set;}
公共字符串名称{get;set;}
公共字符串MAC{get;set;}
}
/*入门级*/
班级计划
{
静态异步void Main(字符串[]args)
{
列表任务=新列表();
对于(int i=2;i==0;i--)
{
Tasks.Add(Task.Factory.StartNew(
()=> {
设备空闲=Helper.GetFreeDevice();
免费返回;
}
));       
}
等待Task.WhenAll(Tasks.ToArray());
foreach(任务中的任务项)
{
控制台写入线(item.Result.IP);
}
Console.ReadLine();
}
}
/*设备助手*/
静态类助手
{
public static List UsedDevices=new List();
公共静态设备GetFreeDevice()
{
联机列出设备=新列表()
{
新设备{IP=“192.168.1.15”,Name=“PerryLabtop”,MAC=“AC:DS:F2:CC:2D:7A”},
新设备{IP=“192.168.1.20”,Name=“MAYA-PC”,MAC=“7D:E9:2C:FF:E7:2D”},
新设备{IP=“192.168.1.2”,Name=“server”,MAC=“D8:C2:A4:DC:E5:3A”}
};
Device FreeDevice=OnlineDevices.Where(x=>!UsedDevices.Contains(x)).SingleOrDefault();
如果(FreeDevice!=null)
UsedDevices.Add(免费设备);
返回自由装置;
}
}
}
//输出
//192.168.1.15  
//192.168.1.15
但预期产出必须保持稳定
//192.168.1.15
//192.168.1.20
调试项目时

所有任务逐行同时执行GetFreeDevice()函数 当前GetFreeDevice()函数执行完成时,我需要让任务等待。。或者任何有用的东西

谢谢大家

试试:

public static Device GetFreeDevice()
    {
         List<Device> OnlineDevices = new List<Device>()
        {
            new Device { IP="192.168.1.15",Name="PerryLabtop",MAC="AC:DS:F2:CC:2D:7A"},
            new Device { IP="192.168.1.20",Name="MAYA-PC",MAC="7D:E9:2C:FF:E7:2D"},
            new Device { IP="192.168.1.2",Name="server",MAC="D8:C2:A4:DC:E5:3A"}
        };

        Device FreeDevice = OnlineDevices.Where(x => !UsedDevices.Contains(x)).SingleOrDefault();
        if (FreeDevice != null)
            lock (UsedDevices)
                UsedDevices.Add(FreeDevice);
        return FreeDevice;
    }
公共静态设备GetFreeDevice()
{
联机列出设备=新列表()
{
新设备{IP=“192.168.1.15”,Name=“PerryLabtop”,MAC=“AC:DS:F2:CC:2D:7A”},
新设备{IP=“192.168.1.20”,Name=“MAYA-PC”,MAC=“7D:E9:2C:FF:E7:2D”},
新设备{IP=“192.168.1.2”,Name=“server”,MAC=“D8:C2:A4:DC:E5:3A”}
};
Device FreeDevice=OnlineDevices.Where(x=>!UsedDevices.Contains(x)).SingleOrDefault();
如果(FreeDevice!=null)
锁(使用的设备)
UsedDevices.Add(免费设备);
返回自由装置;
}
------------------------更新

尝试:

公共静态设备GetFreeDevice()
{
联机列出设备=新列表()
{
新设备{IP=“192.168.1.15”,Name=“PerryLabtop”,MAC=“AC:DS:F2:CC:2D:7A”},
新设备{IP=“192.168.1.20”,Name=“MAYA-PC”,MAC=“7D:E9:2C:FF:E7:2D”},
新设备{IP=“192.168.1.2”,Name=“server”,MAC=“D8:C2:A4:DC:E5:3A”}
};
锁(使用的设备)
{
Device FreeDevice=OnlineDevices.Where(x=>!UsedDevices.Contains(x)).SingleOrDefault();
如果(FreeDevice!=null)
UsedDevices.Add(免费设备);
}
返回自由装置;
}

要使其正常工作,必须解决几个问题:

  • 您可能在
    循环中反转了条件,因为int i=2;i==0;我什么也不做。将
    i==0
    替换为
    i!=0

  • async
    Main方法没有意义(参见示例),实际上甚至不在VisualStudio中编译。要解决此问题,例如,您可以等待任务同步完成(使用
    .wait()
    而不是
    wait

  • 为了防止多个线程同时运行GetFreeDevice()方法,只需在使用共享对象的代码周围加锁即可,在您的示例中,共享对象就是整个方法体

  • 由于每次调用GetFreeDevice()方法时都会创建新的联机设备列表,因此UsedDevices.Contains(x)将无法按预期工作。默认情况下,对象按其引用进行比较。So.Contains(x)将UsedDevices列表中的设备对象(在以前的一次调用中放在那里)与新创建的设备对象进行比较,新创建的设备对象永远不会相等(尽管IP、名称和MAC相同,但这些对象的引用将不同)。要解决这个问题,您可以覆盖设备类上的Equals()和GetHashCode()方法,或者(正如我所做的)只创建一个设备对象的静态列表

  • 必须将SingleOrDefault()替换为FirstOrDefault()。对于SingleOrDefault(),如果有多个未使用的设备,程序将抛出异常,而FirstOrDefault()将获取第一个未使用的设备,即使有多个

  • 完整的源代码和所有建议的修复程序:

    namespace ITDevices
    {
        /*Device Modal*/
        public class Device
        {
            public string IP { get; set; }
            public string Name { get; set; }
            public string MAC { get; set; }
        }
    
        /*Entry Class*/
        class Program
        {
            static void Main(string[] args)
            {
                List<Task<Device>> Tasks = new List<Task<Device>>();
    
                for (int i = 2; i != 0; i--)
                {
                    Tasks.Add(Task.Factory.StartNew<Device>(
                        () => {
                            Device free = Helper.GetFreeDevice();
                            return free;
                        }
                        ));
                }
                Task.WhenAll(Tasks.ToArray()).Wait();
                foreach (Task<Device> item in Tasks)
                {
                    Console.WriteLine(item.Result.IP);
                }
                Console.ReadLine();
            }
        }
        /*Devices Helper*/
        static class Helper
        {
            public static List<Device> UsedDevices = new List<Device>();
    
            static List<Device> OnlineDevices = new List<Device>()
            {
                new Device { IP="192.168.1.15",Name="PerryLabtop",MAC="AC:DS:F2:CC:2D:7A"},
                new Device { IP="192.168.1.20",Name="MAYA-PC",MAC="7D:E9:2C:FF:E7:2D"},
                new Device { IP="192.168.1.2",Name="server",MAC="D8:C2:A4:DC:E5:3A"}
            };
    
            static Object LockObject = new Object();
    
            public static Device GetFreeDevice()
            {
                lock (LockObject)
                {
                    Device FreeDevice = OnlineDevices.Where(x => !UsedDevices.Contains(x)).FirstOrDefault();
                    if (FreeDevice != null)
                        UsedDevices.Add(FreeDevice);
                    return FreeDevice;
                }
            }
        }
    }
    
    名称空间设备
    {
    /*设备模式*/
    公共类设备
    {
    公共字符串IP{get;set;}
    公共字符串名称{get;set;}
    公共字符串MAC{get;set;}
    }
    /*入门级*/
    班级计划
    {
    静态void Main(字符串[]参数)
    {
    列表任务=新列表();
    对于(int i=2;i!=0;i--)
    {
    Tasks.Add(Task.Factory.StartNew(
    () => {
    设备空闲=Helper.GetFreeDevice();
    免费返回;
    }
    ));
    }
    Task.WhenAll(Tasks.ToArray()).Wait();
    foreach(任务中的任务项)
    {
    控制台写入线(item.Result.IP);
    }
    Console.ReadLine();
    }
    }
    /*设备助手*/
    静态类助手
    {
    公共静态列表
    
    public static Device GetFreeDevice()
        {
             List<Device> OnlineDevices = new List<Device>()
            {
                new Device { IP="192.168.1.15",Name="PerryLabtop",MAC="AC:DS:F2:CC:2D:7A"},
                new Device { IP="192.168.1.20",Name="MAYA-PC",MAC="7D:E9:2C:FF:E7:2D"},
                new Device { IP="192.168.1.2",Name="server",MAC="D8:C2:A4:DC:E5:3A"}
            };
    
            lock (UsedDevices)
            {
                Device FreeDevice = OnlineDevices.Where(x => !UsedDevices.Contains(x)).SingleOrDefault();
                if (FreeDevice != null)
                    UsedDevices.Add(FreeDevice);
            }
            return FreeDevice;
        }
    
    namespace ITDevices
    {
        /*Device Modal*/
        public class Device
        {
            public string IP { get; set; }
            public string Name { get; set; }
            public string MAC { get; set; }
        }
    
        /*Entry Class*/
        class Program
        {
            static void Main(string[] args)
            {
                List<Task<Device>> Tasks = new List<Task<Device>>();
    
                for (int i = 2; i != 0; i--)
                {
                    Tasks.Add(Task.Factory.StartNew<Device>(
                        () => {
                            Device free = Helper.GetFreeDevice();
                            return free;
                        }
                        ));
                }
                Task.WhenAll(Tasks.ToArray()).Wait();
                foreach (Task<Device> item in Tasks)
                {
                    Console.WriteLine(item.Result.IP);
                }
                Console.ReadLine();
            }
        }
        /*Devices Helper*/
        static class Helper
        {
            public static List<Device> UsedDevices = new List<Device>();
    
            static List<Device> OnlineDevices = new List<Device>()
            {
                new Device { IP="192.168.1.15",Name="PerryLabtop",MAC="AC:DS:F2:CC:2D:7A"},
                new Device { IP="192.168.1.20",Name="MAYA-PC",MAC="7D:E9:2C:FF:E7:2D"},
                new Device { IP="192.168.1.2",Name="server",MAC="D8:C2:A4:DC:E5:3A"}
            };
    
            static Object LockObject = new Object();
    
            public static Device GetFreeDevice()
            {
                lock (LockObject)
                {
                    Device FreeDevice = OnlineDevices.Where(x => !UsedDevices.Contains(x)).FirstOrDefault();
                    if (FreeDevice != null)
                        UsedDevices.Add(FreeDevice);
                    return FreeDevice;
                }
            }
        }
    }