此代码效果不错,但看起来很糟糕。如何在这种情况下编写漂亮的代码?
您可以在操场上看它: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)
{
}
}
嗯,您可以尝试使用PLinq(Parallel Linq),并摆脱lock
s,Thread
s等
using System.Linq;
...
uidList
.AsParallel()
//.WithMergeOptions(ParallelMergeOptions.NotBuffered)
//.AsOrdered()
.ForAll(item => DoSomeJob(item));
这是使用线程的非常糟糕的方法。启动线程真的很繁琐,当执行一些硬核计算时,它被认为是一个很好的解决方案。在多线程环境中工作时,您需要在两个目标之间进行选择:
为了提高性能,请执行以下操作:
Parallel.ForEach(uidList, DoSomeJob);
这将创建重量级的
Thread
,并且在某个时间点几乎会使用您的全部CPU功能。
对于I / O,请执行以下操作:
private async Task DoSomeJob(int uid){ ... } await Task.WhenAll(uidList.Select(DoSomeJob));
这将需要开发
async
样式,但是Task
是非常轻量的对象,并且您几乎看不到CPU达到1%,因为预计大多数情况下您的任务只是等待某事而已发生,然后发生其他事情,然后所有这些……等等。