C# 在c中使用多线程时如何循环列表#
在使用多线程时,我有一个要循环的列表,我将获取列表的第一项并进行一些处理,然后删除该项。 当列表计数不大于0时,从数据中提取数据 一言以蔽之: 在中,我的数据库中有很多记录。我需要将它们发布到我的服务器。在发布过程中,需要多线程,线程数可能为10或更少 例如:C# 在c中使用多线程时如何循环列表#,c#,multithreading,loops,C#,Multithreading,Loops,在使用多线程时,我有一个要循环的列表,我将获取列表的第一项并进行一些处理,然后删除该项。 当列表计数不大于0时,从数据中提取数据 一言以蔽之: 在中,我的数据库中有很多记录。我需要将它们发布到我的服务器。在发布过程中,需要多线程,线程数可能为10或更少 例如: private List<string> list; void LoadDataFromDatabase(){ list=...;//load data from database... } void DoMethod
private List<string> list;
void LoadDataFromDatabase(){
list=...;//load data from database...
}
void DoMethod()
{
While(list.Count>0)
{
var item=list.FirstOrDefault();
list.RemoveAt(0);
DoProcess();//how to use multi-thread (custom the count of theads)?
if(list.Count<=0)
{
LoadDataFromDatabase();
}
}
}
私有列表;
void LoadDataFromDatabase(){
列表=…;//从数据库加载数据。。。
}
虚空圆顶法()
{
而(列表计数>0)
{
var item=list.FirstOrDefault();
移除列表(0);
DoProcess();//如何使用多线程(自定义线程数)?
如果(list.Count有很多方法可以实现这一点。您可以自己创建线程并对列表进行分区,也可以利用并利用。在链接的示例中,您可以看到对迭代的列表的每个成员都会调用一个操作。如果这是您第一次尝试线程,我也会尝试使用老式的方法方法。有很多方法可以实现这一点。您可以自己创建线程并对列表进行分区,也可以利用并利用。在链接上的示例中,您会看到对列表中的每个成员都会调用一个操作。如果这是您第一次尝试线程,我也会尝试使用老式的方法方法。这是一个简单的方案,如果您在需求中添加一些细节,可以通过多种方式扩展:
IEnumerable<Data> LoadDataFromDatabase()
{
return ...
}
void ProcessInParallel()
{
while(true)
{
var data = LoadDataFromDatabase().ToList();
if(!data.Any()) break;
data.AsParallel().ForEach(ProcessSingleData);
}
}
void ProcessSingleData(Data d)
{
// do something with data
}
IEnumerable LoadDataFromDatabase()
{
返回。。。
}
void ProcessInParallel()
{
while(true)
{
var data=LoadDataFromDatabase().ToList();
如果(!data.Any())中断;
data.aspallel().ForEach(ProcessSingleData);
}
}
void ProcessSingleData(数据d)
{
//处理数据
}
这是一个简单的场景,如果您在需求中添加一些细节,可以通过多种方式扩展:
IEnumerable<Data> LoadDataFromDatabase()
{
return ...
}
void ProcessInParallel()
{
while(true)
{
var data = LoadDataFromDatabase().ToList();
if(!data.Any()) break;
data.AsParallel().ForEach(ProcessSingleData);
}
}
void ProcessSingleData(Data d)
{
// do something with data
}
IEnumerable LoadDataFromDatabase()
{
返回。。。
}
void ProcessInParallel()
{
while(true)
{
var data=LoadDataFromDatabase().ToList();
如果(!data.Any())中断;
data.aspallel().ForEach(ProcessSingleData);
}
}
void ProcessSingleData(数据d)
{
//处理数据
}
这里是我的意见;)
如果你的“列表”不是很大,你可以避免使用多线程
您可以使用队列(FIFO-先进先出)代替列表。然后仅使用Dequeue()方法获取队列的一个元素,DoSomeWork,然后获取另一个元素。类似于:
while(queue.Count > 0)
{
var temp = DoSomeWork(queue.Dequeue());
}
我认为这对你的提议会更好。这是我的意见;)
如果你的“列表”不是很大,你可以避免使用多线程
您可以使用队列(FIFO-先进先出)代替列表。然后仅使用Dequeue()方法获取队列的一个元素,DoSomeWork,然后获取另一个元素。类似于:
while(queue.Count > 0)
{
var temp = DoSomeWork(queue.Dequeue());
}
我认为这对你的提议会更好
我将获取列表的第一项并进行一些处理,然后删除该项
糟糕
首先,您需要的是队列,而不是列表
第二,你不处理然后删除,你删除然后处理
为什么?
因此,您可以保持较小的锁。锁列表访问(注意,您需要同步访问),移除,然后立即解锁,然后进行处理。这样可以缩短锁的长度。如果使用,处理,然后移除-您基本上是单线程的,因为在处理时必须将锁保持在原位,因此下一个线程不会再次使用同一项目
当您需要同步访问并需要多个线程时,这是唯一的方法
请先阅读lock语句(您可以稍后转到类似于spinlock的语句)。不要使用线程,除非您需要安排任务(使用4.0中新增的Tasks接口),这将为您提供更大的灵活性
我将获取列表的第一项并进行一些处理,然后删除该项
糟糕
首先,您需要的是队列,而不是列表
第二,你不处理然后删除,你删除然后处理
为什么?
因此,您可以保持较小的锁。锁列表访问(注意,您需要同步访问),移除,然后立即解锁,然后进行处理。这样可以缩短锁的长度。如果使用,处理,然后移除-您基本上是单线程的,因为在处理时必须将锁保持在原位,因此下一个线程不会再次使用同一项目
当您需要同步访问并需要多个线程时,这是唯一的方法
先阅读lock语句(以后可以转到类似于spinlock的语句)。除非您必须安排任务,否则不要使用线程(使用4.0中新增的任务界面),这为您提供了更大的灵活性。您是否应该按顺序处理列表?换句话说,您不能在尚未完成元素n
处理的情况下处理元素n
?如果您是这样,那么多线程不是正确的解决方案
否则,如果处理元素是完全独立的,则可以使用m
线程,为每个要处理的线程划分elements.Count/m
元素
示例:打印列表:
List<int> a = new List<int> { 1, 2, 3, 4,5 , 6, 7, 8, 9 , 10 };
int num_threads = 2;
int thread_elements = a.Count / num_threads;
// start the threads
Thread[] threads = new Thread[num_threads];
for (int i = 0; i < num_threads; ++i)
{
threads[i] = new Thread(new ThreadStart(Work));
threads[i].Start(i);
}
// this works fine if the total number of elements is divisable by num_threads
// but if we have 500 elements, 7 threads, then thread_elements = 500 / 7 = 71
// but 71 * 7 = 497, so that there are 3 elements not processed
// process them here:
int actual = thread_elements * num_threads;
for (int i = actual; i < a.Count; ++i)
Console.WriteLine(a[i]);
// wait all threads to finish
for (int i = 0; i < num_threads; ++i)
{
threads[i].Join();
}
void Work(object arg)
{
Console.WriteLine("Thread #" + arg + " has begun...");
// calculate my working range [start, end)
int id = (int)arg;
int mystart = id * thread_elements;
int myend = (id + 1) * thread_elements;
// start work on my range !!
for (int i = mystart; i < myend; ++i)
Console.WriteLine("Thread #" + arg + " Element " + a[i]);
}
List a=新列表{1,2,3,4,5,6,7,8,9,10};
int num_线程=2;
int thread_elements=a.计数/num_线程;
//启动线程
线程[]线程=新线程[num_线程];
对于(int i=0;i