在数据网格视图行上循环的快速方法

本文关键字:循环 方法 数据 数据网 网格 视图 | 更新日期: 2023-09-27 18:21:29

我有一个数据网格视图,其中包含一列价格和1000多行我想对所有这些价格进行降价,例如"-20%"

 product    price  
 product1    200
 product2    300
 product3    400

public class product
{
    public int ID {get;set;}
    public double Price {get;set;}
    public string Name {get;set;}
}
public List<product> GetListProduct()
{
       B_Entities dbCtx = new B_Entities();
        return dbCtx.B_PRODUCTS.Select(p => new Product{ ID= p.ID, Name= p.Name, Price= p.Price }).ToList();

}
dgvListeProd.DataSource = GetListProduct(); 
 Parallel.For(0, dgvListeProd.Rows.Count, index=>
            {
                  object priceValue = dgvListeProd.Rows[index].Cells[2].Value;
                if (priceValue != null)
                {
                    decimal price = Convert.ToDecimal(priceValue);
                    decimal countedPrice = (price * pourcentage) / 100;
                     countedPrice = price - countedPrice;
                    dgvListeProd.Rows[index].Cells[2].Value =(double) countedPrice;
                }
            });

这会生成聚合异常。如何以快速方式执行此任务

在数据网格视图行上循环的快速方法

有一件事需要永远记住(至少对于Windows Forms:-)-UI是单线程的,您不能使用多线程技术(包括并行扩展)来"优化"它。

执行更新任务的最快方法是更新数据,并让UI显示您所做的操作。幸运的是,您有一个数据源,所以对数据源应用操作(在这里您可以使用简单的forParallel.For),然后只调用DataGridView.Refresh

这里有一个完整的工作示例,类似于您的案例,它处理1M行,没有任何问题:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Samples
{
    static class Program
    {
        static void ReducePrice(DataGridView productView, decimal percentage)
        {
            var factor = 1 - percentage / 100;
            var data = (List<Product>)productView.DataSource;
            Parallel.For(0, data.Count, index =>
            {
                var product = data[index];
                product.Price = (double)((decimal)product.Price * factor);
            });
            productView.Refresh();
        }
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            var form = new Form();
            var dg = new DataGridView { Dock = DockStyle.Fill, Parent = form };
            dg.DataSource = GetProductList();
            var button = new Button { Dock = DockStyle.Bottom, Parent = form, Text = "Reduce Price by 20%" };
            button.Click += (sender, e) => ReducePrice(dg, 20);
            Application.Run(form);
        }
        static List<Product> GetProductList()
        {
            var random = new Random();
            return Enumerable.Range(1, 1000000).Select(n => new Product { ID = n, Name = "Product#" + n, Price = random.Next(10, 1000) }).ToList();
        }
    }
    public class Product
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public double Price { get; set; }
    }
}