C# 多线程 线程池 遍历 DataTable 怎么让多线程,线程池的操作循环完DataTable 再 走下面的方法 等线程的操作全部循环结束后再走下面的方法 请给案例
额,这种事情都不必要强调线程不线程,时代在发展。20年前人们口里的宝贝,如今其实早就不当回事了
你这要求我们直接plinq即可(虽然他内部用了,但是我觉得不必强调,天天口里强调那些的,教出来的反而不会写代码了,因为他们把这些玩意看得太高级,太有技术了,所以反而忘了简单快乐的写代码。何必天天闹心掉头发的折腾20年前的高级)
DataTable dt = new DataTable();
dt.Columns.Add("id", typeof(Int32));
dt.LoadDataRow(new Object[] { 1 }, true);
dt.LoadDataRow(new Object[] { 2 }, true);
dt.LoadDataRow(new Object[] { 3 }, true);
dt.LoadDataRow(new Object[] { 4 }, true);
dt.AsEnumerable().AsParallel().ForAll(row =>
{
Processrow(row);
});
Console.WriteLine("已经循环完毕");
void Processrow(DataRow row)
{
//打印rowid和执行线程id
Console.WriteLine($"{row["id"]}--{Thread.CurrentThread.ManagedThreadId}");
Thread.Sleep(1000*5); //加个5秒延迟是让你能明显看到,你他全部执行完毕后才会进入后面的
}
直接调用线程池的相关方法,threadpool
该回答引用GPTᴼᴾᴱᴺᴬᴵ
以下是一个使用线程池遍历DataTable的示例代码,同时等待所有线程完成后再执行下一步操作:
using System;
using System.Data;
using System.Threading;
using System.Threading.Tasks;
class Program
{
static void Main(string[] args)
{
DataTable dt = new DataTable();
// 填充DataTable...
int numThreads = Environment.ProcessorCount; // 使用CPU核心数作为线程池线程数
int rowCount = dt.Rows.Count;
int chunkSize = (int)Math.Ceiling(rowCount / (double)numThreads);
ManualResetEvent[] resetEvents = new ManualResetEvent[numThreads];
for (int i = 0; i < numThreads; i++)
{
resetEvents[i] = new ManualResetEvent(false);
int start = i * chunkSize;
int end = (i == numThreads - 1) ? rowCount : (i + 1) * chunkSize;
ThreadPool.QueueUserWorkItem((object state) =>
{
try
{
for (int j = start; j < end; j++)
{
// 处理dt.Rows[j]...
}
}
finally
{
resetEvents[(int)state].Set();
}
}, i);
}
WaitHandle.WaitAll(resetEvents); // 等待所有线程完成
// 所有线程处理完后执行下一步操作...
}
}
在上述代码中,我们将CPU核心数作为线程池线程数,并将数据表的行分成多个块进行处理。每个线程处理一个块的行,并使用ManualResetEvent来跟踪每个线程的状态。WaitHandle.WaitAll(resetEvents)方法会等待所有线程完成后再执行下一步操作。在线程内部处理完成后,我们使用ManualResetEvent.Set()方法来标记线程完成。
参考GPT和自己的思路:
可以使用CountdownEvent或者ManualResetEvent来实现等待多个线程完成后再执行下一步操作。下面是一个使用CountdownEvent的示例代码:
// 创建一个CountdownEvent,初始计数为DataTable的行数
CountdownEvent countdownEvent = new CountdownEvent(dataTable.Rows.Count);
// 使用线程池执行遍历DataTable的任务
for (int i = 0; i < dataTable.Rows.Count; i++)
{
ThreadPool.QueueUserWorkItem(state =>
{
// 处理DataTable中的一行数据
// 每处理完一行数据,就将CountdownEvent的计数减1
countdownEvent.Signal();
});
}
// 等待所有线程完成任务
countdownEvent.Wait();
// 所有线程都完成任务后,执行下面的方法
DoNextStep();
上面的代码中,首先创建了一个CountdownEvent,初始计数为DataTable的行数。然后使用线程池执行遍历DataTable的任务,在处理完每一行数据后,都会调用CountdownEvent的Signal方法将计数减1。最后调用CountdownEvent的Wait方法等待所有线程完成任务。当CountdownEvent的计数减为0时,就表示所有线程都完成任务,就可以执行下面的方法了。