此代码效果很好,但看起来很糟糕。如何在这种情况下编写漂亮的代码?
您可以在操场上看它:https://dotnetfiddle.net/GUZni0
或以下代码:
using System;
using System.Collections.Generic;
using System.Threading;
public class Program
{
static object valueLocker = new Object();
static List<int> uidList;
static int takeuid = -1;
static int countThreads = 0;
public static void Main()
{
for (;;) {
Console.WriteLine("Hello World");
uidList = new List<int>();
uidList.Add(0);
uidList.Add(1);
uidList.Add(2);
uidList.Add(3);
uidList.Add(4);
countThreads = 0;
for (int i = 0; i < 10; i++)
{
Thread thread = new Thread(TakeUidThread);
thread.Start();
}
线程完成后,每0.5秒检查一次主线程并获取新的uidList
while (countThreads < 10)
{
Thread.Sleep(500);
}
Console.WriteLine("All threads finished");
}
}
public static void TakeUidThread()
{
var localuid = -1;
while (localuid < uidList.Count)
{
// thread takes free uid
lock (valueLocker)
{
takeuid++;
localuid = takeuid;
}
if (localuid < uidList.Count && localuid != -1)
{
DoSomeJob(uidList[localuid]);
}
}
Thread inc countThreads结尾
lock (valueLocker)
{
countThreads++;
}
}
private static void DoSomeJob(int uid)
{
}
}
答案 0 :(得分:2)
好吧,您可以尝试使用 PLinq ( Parallel Linq),并摆脱lock
,Thread
等。< / p>
using System.Linq;
...
uidList
.AsParallel()
//.WithMergeOptions(ParallelMergeOptions.NotBuffered)
//.AsOrdered()
.ForAll(item => DoSomeJob(item));
答案 1 :(得分:1)
这是使用线程的一种非常糟糕的方法。启动线程是一件很繁重的事情,只有在执行一些核心计算时才被认为是一个好的解决方案。在多线程环境中工作时,需要在两个目标之间进行选择:
为提高性能,您可以这样做:
Parallel.ForEach(uidList, DoSomeJob);
这将创建重量级的Thread
,并在某个时间点几乎消耗掉整个CPU的功能。
对于I / O,请执行以下操作:
private async Task DoSomeJob(int uid){ ... }
await Task.WhenAll(uidList.Select(DoSomeJob));
这将需要async
样式的开发,但是Task
是一个非常轻量的对象,并且您几乎看不到CPU达到甚至1%的水平,因为预计大多数时候您的任务除了等待某事发生,然后再发生某事,然后所有这些……等等,什么都不做。