C# 将普通回路更改为并行回路

C# 将普通回路更改为并行回路,c#,.net,parallel.foreach,C#,.net,Parallel.foreach,我有以下代码: static void Main(string[] args) { TaskExecuter.Execute(); } class Task { int _delay; private Task(int delay) { _delay = delay; } public void Execute() { Thread.Sleep(_delay); } public static IEnumerable Get

我有以下代码:

static void Main(string[] args)
{
   TaskExecuter.Execute();
}

class Task
{
        int _delay;
        private Task(int delay) { _delay = delay; }
        public void Execute() { Thread.Sleep(_delay); }
        public static IEnumerable GetAllTasks()
        {
            Random r = new Random(4711);
            for (int i = 0; i < 10; i++)
                yield return new Task(r.Next(100, 5000));
        }
 }

static class TaskExecuter
{
        public static void Execute()
        {
            foreach (Task task in Task.GetAllTasks())
            {
                 task.Execute();
            }
        }
   }

这对我的linqpad有效。我刚刚将您的
Task
类重命名为
Work
,并从
GetAllTasks
返回了一个
IEnumerable

class Work
{
        int _delay;
        private Work(int delay) { _delay = delay; }
        public void Execute() { Thread.Sleep(_delay); }
        public static IEnumerable<Work> GetAllTasks()
        {
            Random r = new Random(4711);
            for (int i = 0; i < 10; i++)
                yield return new Work(r.Next(100, 5000));
        }
 }

static class TaskExecuter
{
        public static void Execute()
        {
            foreach (Work task in Work.GetAllTasks())
            {
                 task.Execute();
            }
        }
   }
void Main()
{
    System.Threading.Tasks.Parallel.ForEach(Work.GetAllTasks(), new Action<Work>(task =>
{
   //Execute();
}));
}
课堂作业
{
内部延迟;
私人工作(int delay){u delay=delay;}
public void Execute(){Thread.Sleep(_delay);}
公共静态IEnumerable GetAllTasks()
{
随机r=新随机(4711);
对于(int i=0;i<10;i++)
收益回报新工作(r.Next(1005000));
}
}
静态类任务执行器
{
公共静态void Execute()
{
foreach(Work.GetAllTasks()中的工作任务)
{
task.Execute();
}
}
}
void Main()
{
System.Threading.Tasks.Parallel.ForEach(Work.GetAllTasks(),新操作(task=>
{
//执行();
}));
}

这在我的linqpad上起了作用。我刚刚将您的
Task
类重命名为
Work
,并从
GetAllTasks
返回了一个
IEnumerable

class Work
{
        int _delay;
        private Work(int delay) { _delay = delay; }
        public void Execute() { Thread.Sleep(_delay); }
        public static IEnumerable<Work> GetAllTasks()
        {
            Random r = new Random(4711);
            for (int i = 0; i < 10; i++)
                yield return new Work(r.Next(100, 5000));
        }
 }

static class TaskExecuter
{
        public static void Execute()
        {
            foreach (Work task in Work.GetAllTasks())
            {
                 task.Execute();
            }
        }
   }
void Main()
{
    System.Threading.Tasks.Parallel.ForEach(Work.GetAllTasks(), new Action<Work>(task =>
{
   //Execute();
}));
}
课堂作业
{
内部延迟;
私人工作(int delay){u delay=delay;}
public void Execute(){Thread.Sleep(_delay);}
公共静态IEnumerable GetAllTasks()
{
随机r=新随机(4711);
对于(int i=0;i<10;i++)
收益回报新工作(r.Next(1005000));
}
}
静态类任务执行器
{
公共静态void Execute()
{
foreach(Work.GetAllTasks()中的工作任务)
{
task.Execute();
}
}
}
void Main()
{
System.Threading.Tasks.Parallel.ForEach(Work.GetAllTasks(),新操作(task=>
{
//执行();
}));
}
接受一个
IEnumerable
,因此您的代码应该是很好的。但是,您需要对作为参数传递给lambda语句的
任务
实例执行
Execute
调用

Parallel.ForEach(Task.GetAllTasks(), task =>
{
    task.Execute();
});
这也可以表示为一行lambda表达式:

Parallel.ForEach(Task.GetAllTasks(), task => task.Execute());

代码中还有另一个需要注意的微妙缺陷。根据其内部实现,
Parallel.ForEach
may。但是,您正在枚举器中调用
Random
类的实例方法,这不是线程安全的,可能会导致争用问题。解决此问题的最简单方法是将序列预先填充为列表:

Parallel.ForEach(Task.GetAllTasks().ToList(), task => task.Execute());

需要一个
IEnumerable
,因此您的代码应该是很好的。但是,您需要对作为参数传递给lambda语句的
任务
实例执行
Execute
调用

Parallel.ForEach(Task.GetAllTasks(), task =>
{
    task.Execute();
});
这也可以表示为一行lambda表达式:

Parallel.ForEach(Task.GetAllTasks(), task => task.Execute());

代码中还有另一个需要注意的微妙缺陷。根据其内部实现,
Parallel.ForEach
may。但是,您正在枚举器中调用
Random
类的实例方法,这不是线程安全的,可能会导致争用问题。解决此问题的最简单方法是将序列预先填充为列表:

Parallel.ForEach(Task.GetAllTasks().ToList(), task => task.Execute());

并行。ForEach
使用
IEnumerable
,因此调整
GetAllTasks
以返回
IEnumerable


net也广泛使用了任务类,我会避免这样命名自己的类以避免混淆

并行。ForEach
使用
IEnumerable
,因此调整
GetAllTasks
以返回
IEnumerable


net也广泛使用了任务类,我会避免这样命名自己的类以避免混淆

也许这会有帮助:@Giedrius谢谢你,如果这是我给你的答案,这是正确的。你可能不应该给你的班级打电话
Task
,以免与
System.Threading.Tasks.Task
混淆。也许这会有帮助:@Giedrius谢谢你,如果这是我给你的答案,你可能不应该调用你的类
Task
,以免与
系统混淆。Threading.Tasks.Task
并行。ForEach()可以从多个线程枚举,但不能并行。它使用锁定来确保一次只枚举一个线程。所以
Random
的用法很好。@svick:你说得对;我被链接帖子中的第一个回复误导了(这是一位知名投稿人写的)。感谢您的澄清。
Parallel.ForEach()
可以从多个线程枚举,但不能并行。它使用锁定来确保一次只枚举一个线程。所以
Random
的用法很好。@svick:你说得对;我被链接帖子中的第一个回复误导了(这是一位知名投稿人写的)。谢谢你的澄清。