c# DataTable dt_JmMll,如果放在Task.Run(() =>)里面直接执行代码是有数据的
如图
Task task = Task.Run(() =>
{
data_JmMll = dd.OpenFileWS(tbpathE.Text);//调用打开,读取用户打开的txt文件,赋值给data_JmMll集合
DataTable dt_JmMll = new DataTable("Number");
DataColumn dc00 = dt_JmMll.Columns.Add("序号", typeof(string));
DataColumn dc000 = dt_JmMll.Columns.Add("供应商", typeof(string));
DataColumn dc1 = dt_JmMll.Columns.Add("条码", typeof(string));
DataColumn dc2 = dt_JmMll.Columns.Add("名称", typeof(string));
DataColumn dc5 = dt_JmMll.Columns.Add("类别", typeof(string));
DataColumn dc3 = dt_JmMll.Columns.Add("进价", typeof(string));
DataColumn dc4 = dt_JmMll.Columns.Add("售价", typeof(string));
DataColumn dc6 = dt_JmMll.Columns.Add("库存", typeof(string));
int Itbtrue = 0;int Itbgood = 0;int k = 1;
InsertEvent += new Insert(BsMerge_InsertEvent);//使用事件方法,同步显示数据 避免假死出现
SetProgressbar(0, data_JmMll.Count);
for (int j = 0; j < data_JmMll.Count; j++)
{
Gressbar(j);//调用方法,赋值给MgBar1
string aa = data_JmMll[j].ToString().Replace("\t", "").Replace(" ", "").Trim();
DataTable dt1 = Stock.CPublic.DT("SELECT t_goods.vendorno,t_goods.barcode,t_goods.itemname,s_class.descr as 类别,t_goods.purprice,t_goods.saleprice,t_depot_h.itemqty as 库存 FROM t_depot_h,t_goods,s_class WHERE ( t_depot_h.itemno = t_goods.itemno ) and ( s_class.classcode = t_goods.classcode ) and t_goods.barcode='" + aa + "' ");
if (dt1.Rows.Count > 0)//Rows.Count =0 代表数据库没记录即是新品
{
DataRow dr;
dr = dt_JmMll.NewRow();
dr["序号"] = j + 1;//使用j 保留txt对应的序号
dr["条码"] = aa;
dr["供应商"] = dt1.Rows[0][0].ToString().Replace("\t", "").Replace(" ", "").Trim();
dr["名称"] = dt1.Rows[0][2].ToString().Replace("\t", "").Replace(" ", "").Trim();
dr["类别"] = dt1.Rows[0][3].ToString().Replace("\t", "").Replace(" ", "").Trim();
dr["进价"] = dt1.Rows[0][4].ToString().Replace("\t", "").Replace(" ", "").Trim();
dr["售价"] = dt1.Rows[0][5].ToString().Replace("\t", "").Replace(" ", "").Trim();
dr["库存"] = dt1.Rows[0][6].ToString().Replace("\t", "").Replace(" ", "").Trim();
dt_JmMll.Rows.Add(dr);
Itbtrue++;
k++;
}
Itbgood++;
if (InsertEvent != null) { BsMerge_InsertEvent(null, j + 1, data_JmMll.Count); }//使用事件,动态显示数据,且窗口不假死
}
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
dataGridView1.DataSource = dt_JmMll;// 在这里执行界面操作【解释:使用 Task.Run 中的代码中触发了界面操作,而界面操作必须在主线程中执行。可以通过在界面操作前使用 Control.Invoke 或者 Dispatcher.Invoke 来确保界面操作在主线程中执行。这样可以确保界面操作在主线程中执行,避免出现跨线程操作界面导致的异常。】
});
}
else { }
//UpdateUIDatagridview();//调用方法使用Invoke 更新ui,避免线程报错
});
问题是:如果是在Task.Run(() =>)里面直接执行代码,在循环后通过调用UpdateUIDatagridview()更新ui方法DataTable数据变0了,请问大咖们帮看看因为啥,两者其实没啥区别
如图:
UpdateUIDatagridview();//调用方法使用Invoke 更新ui,避免线程报错
private void UpdateUIDatagridview()
{
#region
//方法一:
//dataGridView1.Invoke(new Action(() =>
//{
// dataGridView1.DataSource = dt_JmMll;
//}));
#endregion
//方法二:原理:// 更新UI的操作需要放在UI线程中进行 如果需要更新UI,使用Invoke方法来调用主线程
if (this.InvokeRequired)
{
this.Invoke((MethodInvoker)delegate
{
dataGridView1.DataSource = dt_JmMll;// 在这里执行界面操作【解释:使用 Task.Run 中的代码中触发了界面操作,而界面操作必须在主线程中执行。可以通过在界面操作前使用 Control.Invoke 或者 Dispatcher.Invoke 来确保界面操作在主线程中执行。这样可以确保界面操作在主线程中执行,避免出现跨线程操作界面导致的异常。】
});
}
else { }
}