在数据网格视图行上循环的快速方法
本文关键字:循环 方法 数据 数据网 网格 视图 | 更新日期: 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显示您所做的操作。幸运的是,您有一个数据源,所以对数据源应用操作(在这里您可以使用简单的for
或Parallel.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; }
}
}