【发布时间】:2017-07-18 17:18:19
【问题描述】:
我是这个多线程概念的新手,我花了很多时间做我的 RnD,但无法完成任务。我正在尝试做的类似于交易应用程序。我有一个 Windows 窗体中的 datagridview,其中显示了来自 sql 数据库的多条记录。它有 4 列(十进制值)。我也有每分钟更新的 txt 文件。我必须从 txt 文件中读取最新的一行,并将这一行的十进制值与 datagridview 中的每个十进制列进行比较。基于此比较,我正在尝试更改 gridview 单元格的颜色。我发现我的代码在逻辑上是正确的,但不知何故它不起作用。对于网格中的每一行,一个线程应该启动,但只有一个线程启动,用于网格中的最后一条记录。我已附上我的代码。请帮助我用这个。 **InitiateAlert :: 它应该遍历网格并为每条记录启动一个新线程。
checkiftargetreached :: 每个线程都应该带参数调用这个函数。这里进行了十进制值的比较并设置了网格单元格颜色。**
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();
}
}
}
【问题讨论】:
-
如果您的网格有 300 行会怎样?你会产生 300 个线程吗?您应该使用文件系统观察程序生成一个线程并使用它定期检查文件。 (假设您必须为此使用文件,这远非最佳。)
-
要比较的十进制值在 txt 文件中可用,由其他工具生成。所以我必须读取这些文件,没有其他选择。我可以根据您的建议只生成一个线程。但在这种情况下,我仍然想知道为什么只产生一个线程(循环中的最后一个)。
标签: c# multithreading winforms datagridview