Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/vb.net/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在c中使用多线程时如何循环列表#_C#_Multithreading_Loops - Fatal编程技术网

C# 在c中使用多线程时如何循环列表#

C# 在c中使用多线程时如何循环列表#,c#,multithreading,loops,C#,Multithreading,Loops,在使用多线程时,我有一个要循环的列表,我将获取列表的第一项并进行一些处理,然后删除该项。 当列表计数不大于0时,从数据中提取数据 一言以蔽之: 在中,我的数据库中有很多记录。我需要将它们发布到我的服务器。在发布过程中,需要多线程,线程数可能为10或更少 例如: private List<string> list; void LoadDataFromDatabase(){ list=...;//load data from database... } void DoMethod

在使用多线程时,我有一个要循环的列表,我将获取列表的第一项并进行一些处理,然后删除该项。 当列表计数不大于0时,从数据中提取数据

一言以蔽之: 在中,我的数据库中有很多记录。我需要将它们发布到我的服务器。在发布过程中,需要多线程,线程数可能为10或更少

例如:

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