C# 多线程 线程池 遍历 DataTable

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时,就表示所有线程都完成任务,就可以执行下面的方法了。