且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

我可以在C#中的数据表中向数据行添加数据时使用多线程吗?

更新时间:2023-12-01 09:31:10

尝试Parallel.ForEach



如何:编写一个简单的Parallel.ForEach循环Microsoft Docs [ ^ ]



无法保证它会提高性能,涉及的因素很多例如您网站服务器上的核心数,SQL服务器架构和各种类型。您更有可能获得更好的性能重构功能,或者不使用其他方法来获取数据库中的数据。
Try Parallel.ForEach

How to: Write a Simple Parallel.ForEach Loop | Microsoft Docs[^]

There is no guarantee it'll increase performance, there are many factors involved in that such as how many cores on your site's server, the SQL server architecture and all sorts. You're more likely to get better performance refactoring your function, or not using some other method to get the data in your database.


我会使用SemaphoreSlim 。这是一个将数据库并发读取数量设置到预设级别的类。达到该级别后,必须在允许开始新读取之前完成现有读取。

I would use a SemaphoreSlim. This is a class that 'gates' the number of concurrent reads of a database to a preset level. Once that level has been reach, an existing read has to finish before a new read is allowed to start.

//A method to asynchronously load data from the database
private async Task<Order> LoadOrderFromDbAsync(int orderId){//....}
 private SemaphoreSlim semaphoreSlim;
 private async Task<List<Order>> GatedConcurrentLoadOfOrdersAsync(IEnumerable<int> orderIds)
        {
           using (semaphoreSlim = new SemaphoreSlim(maxConcurrencyLevel))
          {
            var tasks = new List<Task<Order>>();
            foreach (int orderId in orderIds)
            {
                //start each task off but don't await it
                //tasks are started by simply invoking the async method
                Task<Order> task = GatedLoadOrderFromDatabaseAsync(orderId);
                tasks.Add(task);
            }

            //await them all to complete
            Order[] loadedOrders = await Task.WhenAll(tasks);
            return loadedOrders.ToList();
         }
        }

 private async Task<Order> GatedLoadOrderFromDatabaseAsync(int orderId)
        {
            //queue here if max number of threads are already active
            await semaphoreSlim.WaitAsync();
           try
            {
              return  await LoadOrderFromDbAsync(orderId);
                
            }
            finally
            {
                //open the gate to let a queued thread run
                semaphoreSlim.Release();
            }
        }


在向DataTable添加行时?不是。



来自DataTable上的MSDN文档:

While ADDING rows to a DataTable? Not really.

From the MSDN documentation on the DataTable:
Quote:

这种类型对于多线程读取操作是安全的。您必须同步任何写操作。

This type is safe for multithreaded read operations. You must synchronize any write operations.



虽然可以使用多个线程将记录添加到DataTable对象,但必须同步向DataTable添加行。这意味着一次只有一个线程可以向表中添加DataRow,实际上将操作转换为单线程操作。使用多个线程几乎没有性能优势。



真正的问题应该是为什么你首先要向DataTable对象添加这么多行?很可能你不需要DataTable中的所有行。


While it is possible to use multiple threads to add records to a DataTable object, adding rows to a DataTable must be synchronized. This means that only one thread can add a DataRow to the table at a time, essentially turning the operation into a single threaded operation. You will get little to no performance benefit from using multiple threads.

The real question should be why are you adding so many rows to a DataTable object in the first place? Chances are good you don't need all of those rows in the DataTable.