C# 如何使用多线程更新datagridview

C# 如何使用多线程更新datagridview,c#,multithreading,winforms,datagridview,C#,Multithreading,Winforms,Datagridview,我不熟悉这个多线程概念,花了很多时间做我的RnD,但没能完成。我尝试做的与交易应用程序类似。我有一个windows窗体中的datagridview,其中显示了来自sql数据库的多条记录。它有4列(十进制值)。我还有每分钟更新的txt文件。我必须从txt文件中读取最新的一行,并将这一行的十进制值与datagridview中的每个十进制列进行比较。基于这个比较,我试图改变gridview单元格的颜色。我发现我的代码在逻辑上是正确的,但不知何故它不起作用。对于网格中的每一行,应该启动一个线程,但只有一

我不熟悉这个多线程概念,花了很多时间做我的RnD,但没能完成。我尝试做的与交易应用程序类似。我有一个windows窗体中的datagridview,其中显示了来自sql数据库的多条记录。它有4列(十进制值)。我还有每分钟更新的txt文件。我必须从txt文件中读取最新的一行,并将这一行的十进制值与datagridview中的每个十进制列进行比较。基于这个比较,我试图改变gridview单元格的颜色。我发现我的代码在逻辑上是正确的,但不知何故它不起作用。对于网格中的每一行,应该启动一个线程,但只有一个线程启动,这是网格中的最后一条记录。。我已附加了我的代码。请帮我完成此操作。 **InitiateAllert::它应该在网格上循环,并为每个记录启动一个新线程

checkiftargetreached::每个线程都应该使用参数调用此函数。此处,十进制值的比较为doen,并设置网格单元颜色**
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用系统文本;
使用系统线程;
使用System.Threading.Tasks;
使用System.Windows.Forms;
使用System.IO;
命名空间多线程示例
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有void b显示\单击(对象发送者,事件参数e)
{
数据集ds=新数据集();
DataTable dt=新的DataTable(“MyTable”);
添加(新的数据列(“id”,typeof(int));
添加(新数据列(“Val1”,类型为(十进制));
添加(新数据列(“Val2”,类型为(十进制));
添加(新数据列(“Val3”,类型为(十进制));
添加(新的数据列(“标志”,typeof(布尔));
DataRow dr=dt.NewRow();
dr[“id”]=1;
dr[“Val1”]=23104.10;
dr[“Val2”]=23154.10;
dr[“Val3”]=23845.45;
dr[“Flag”]=true;
dt.Rows.Add(dr);
dr=dt.NewRow();
dr[“id”]=2;
dr[“Val1”]=25104.10;
dr[“Val2”]=25154.10;
dr[“Val3”]=25845.45;
dr[“Flag”]=true;
dt.Rows.Add(dr);
dataGridView1.DataSource=dt;
}
私有void checkIftargetrached(Int32行ID、十进制值1、十进制值2、十进制值3、字符串文件路径)
{
弦线;
尝试
{
while(Convert.ToInt16(此.dataGridView1.Rows[rowid].Cells[“Flag”].Value)==1)
{
FileStream fs=newfilestream(“C:\\Users\\username\\Downloads\\”+文件路径,FileMode.Open,FileAccess.Read,FileShare.ReadWrite);
StreamReader sr=新的StreamReader(fs);
DataTable dtrec=新DataTable();
line=sr.ReadLine();
string[]value=line.Split(',');

对于(inti=0;i,这里有一个来自微软的教程

微软说你需要使用“virtualmode”


这个问题与虚拟模式无关。如果网格有300行,会发生什么?您会生成300个线程吗?您应该生成一个线程,并使用它定期检查文件,使用文件系统监视程序。(假设您必须为此使用文件,这远远不是最佳选择。)要比较的十进制值在其他工具生成的txt文件中可用。因此我必须读取这些文件,没有其他选项。我可以按照您的建议只生成一个线程。但在这种情况下,我仍然想知道为什么只生成一个线程(循环中的最后一个)。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO;

namespace MultithredingSample
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        private void btnshow_Click(object sender, EventArgs e)
        {
            DataSet ds = new DataSet();

            DataTable dt = new DataTable("MyTable");
            dt.Columns.Add(new DataColumn("id", typeof(int)));
            dt.Columns.Add(new DataColumn("Val1", typeof(decimal)));
            dt.Columns.Add(new DataColumn("Val2", typeof(decimal)));
            dt.Columns.Add(new DataColumn("Val3", typeof(decimal)));
            dt.Columns.Add(new DataColumn("Flag", typeof(Boolean)));

            DataRow dr = dt.NewRow();
            dr["id"] = 1;
            dr["Val1"] = 23104.10;
            dr["Val2"] = 23154.10;
            dr["Val3"] = 23845.45;
            dr["Flag"] = true;
            dt.Rows.Add(dr);


            dr = dt.NewRow();
            dr["id"] = 2;
            dr["Val1"] = 25104.10;
            dr["Val2"] = 25154.10;
            dr["Val3"] = 25845.45;
            dr["Flag"] = true;
            dt.Rows.Add(dr);



            dataGridView1.DataSource = dt;


        }


private void checkiftargetreached(Int32 rowid,decimal val1,decimal val2, decimal val3, string filepath)
{
string line;
try
   {

   while (Convert.ToInt16(this.dataGridView1.Rows[rowid].Cells["Flag"].Value) == 1)
   {

    FileStream fs = new FileStream("C:\\Users\\username\\Downloads\\" + filepath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
    StreamReader sr = new StreamReader(fs);
    DataTable dtrec = new DataTable();
    line = sr.ReadLine();
    string[] values = line.Split(',');
    for (int i = 0; i <= values.Length - 1; i++)
    {dtrec.Columns.Add(values[i]);}

  line = sr.ReadLine();
  DataRow dr = dtrec.NewRow();
  string[] values2 = line.Split(',');
  for (int i = 0; i <= values2.Length - 1; i++)
  {dr[i] = values2[i];}
  dtrec.Rows.Add(dr);
  if(Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val1"].Value))
    {
     if (this.dataGridView1.InvokeRequired){
this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val1"].Style.BackColor = Color.Aqua; });
                        }

                    }
  else if (Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val2"].Value))
                    {
                        if (this.dataGridView1.InvokeRequired)
                        {
                            this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val2"].Style.BackColor = Color.Aqua; this.dataGridView1.Rows[rowid].Cells["Flag"].Value = 0; });
                        }

                    }
                    else if (Convert.ToDecimal(dtrec.Rows[0][1]) == Convert.ToDecimal(this.dataGridView1.Rows[rowid].Cells["Val3"].Value))
                    {

                        if (this.dataGridView1.InvokeRequired)
                        {
                            this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val3"].Style.BackColor = Color.Aqua; });

                        }

                    }
                    else
                    {

                        if (this.dataGridView1.InvokeRequired)
                        {
                            this.dataGridView1.BeginInvoke((MethodInvoker)delegate () { this.dataGridView1.Rows[rowid].Cells["Val3"].Style.BackColor = Color.IndianRed; });
                        }
                    }



                }


            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }

        }

        private void InitiateAlerts()
        {
            Int32 row;
            decimal val1, val2, val3;

            try
            {
                for (int j = 0; j <= dataGridView1.Rows.Count - 1; j++)
                {

                    if (this.dataGridView1.InvokeRequired)
                    {
                        this.dataGridView1.BeginInvoke((MethodInvoker)delegate ()
                        {


                            if (Convert.ToInt16(this.dataGridView1.Rows[j].Cells["Flag"].Value) == 1)
                            {

                                row = j;
                                val1 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val1"].Value);
                                val2 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val2"].Value);
                                val3 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val3"].Value);

                                Thread TH = new Thread(() => checkiftargetreached(row, val1, val2, val3, "A" + row.ToString() + ".txt"));
                                TH.Name = "A" + row.ToString() + ".csv";
                                TH.Start();
                            }

                        });


                    }
                    else
                    {

                        if (Convert.ToInt16(this.dataGridView1.Rows[j].Cells["Flag"].Value) == 1)
                        {

                            row = j;
                            val1 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val1"].Value);
                            val2 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val2"].Value);
                            val3 = Convert.ToDecimal(this.dataGridView1.Rows[row].Cells["Val3"].Value);

                            Thread TH = new Thread(() => checkiftargetreached(row, val1, val2, val3, "A" + row.ToString() + ".txt"));
                            TH.Name = "A" + row.ToString() + ".csv";
                            TH.Start();
                        }

                    }

                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }


        }

        private void btnthread_Click(object sender, EventArgs e)
        {
            InitiateAlerts();
        }
    }
}