在进行Winform程序开发需要进行大量的数据的读写操作的时候,往往会需要一定的时间,然在这个时间段里面,界面ui得不到更新,导致在用户看来界面处于假死的状态,造成了不好的用户体验。所以在大量数据操作的应用上,需要使用多线程来处理这种情况。在c#中使用多线程很方便只需要使用System.Threading.Thread的一个实例的Start方法就行了,但是如何实现多线程之间的交互就不是那么简单。本文实现了用子线程去处理数据,并实时更新主线程的ui状态了。
1、首先要建立一个委托来实现非创建控件的线程更新控件。
2、然后编写多线程去启动写入数据的方法以及回调的函数。
public partial class ucPrice : UserControl
{
SQLiteConnection conn;
//定义委托
delegate void inittvItemsDelegate();
delegate void AsynUpdateUI1(string step); //更新UI1
delegate void AsynUpdateUI2(TreeNode root);//更新UI2
public delegate void UpdateUI(string step);//声明一个更新主线程的委托
public UpdateUI UpdateUIDelegate;
public delegate void AccomplishTask(TreeNode root);//声明一个在完成任务时通知主线程的委托
public AccomplishTask TaskCallBack;
public ucPrice()
{
InitializeComponent();
twItems.Nodes.Add("正在连接数据库");
UpdateUIDelegate += UpdataUIStatus;//绑定更新任务状态的委托
TaskCallBack += Accomplish;//绑定完成任务要调用的委托
//启动线程
Thread thread = new Thread(intitvItems);
thread.IsBackground = true;
thread.Start();
//intitvItems();
}
//更新UI
private void UpdataUIStatus(string step)
{
if (InvokeRequired)
{
this.Invoke(new AsynUpdateUI1(delegate (string s)
{
//this.pgbWrite.Value += s;
//this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
twItems.Nodes.Add(s);
}), step);
}
}
//完成任务时需要调用
private void Accomplish(TreeNode root)
{
if (InvokeRequired)
{
this.Invoke(new AsynUpdateUI2(delegate (TreeNode rt)
{
//this.pgbWrite.Value += s;
//this.lblWriteStatus.Text = this.pgbWrite.Value.ToString() + "/" + this.pgbWrite.Maximum.ToString();
twItems.Nodes.Clear();
twItems.Nodes.Add(rt);
}), root);
}
}
private void ucPrice_Load(object sender, System.EventArgs e)
{
}
private void intitvItems()
{
TreeNode root = new TreeNode();
root.Tag = 0;
root.Text = "物品数据库-"+ "YC122";
root.Expand();
// twItems.Nodes.Add(root);
try
{
conn = new SQLiteConnection("Data Source=db/eve.db;Version=3;");
conn.Open();
UpdateUIDelegate("数据库已连接,正在加载数据...");
}
catch(Exception ex)
{
throw ex;
}
setTreeView(root, 0);
UpdateUIDelegate("市场组数据加载完毕,正在加载物品数据");
setTreeViewLeaf(root);
UpdateUIDelegate("物品组数据加载完毕.");
TaskCallBack(root);
}
///
/// 查找叶子节点
///
///
private void setTreeViewLeaf(TreeNode tr1)
{
foreach(TreeNode node in tr1.Nodes)
{
//查找树的叶子节点
if(node.Nodes.Count==0)
{
addNodeLeaf(node);
}
else
{
findTreeViewLeaf(node);
}
UpdateUIDelegate("加载物品组"+node.Text);
}
}
///
/// 第二层遍历,加速函数
///
///
private void findTreeViewLeaf(TreeNode tr1)
{
foreach (TreeNode node in tr1.Nodes)
{
//查找树的叶子节点
if (node.Nodes.Count == 0)
{
addNodeLeaf(node);
}
else
{
flashTreeViewLeaf(node);
}
}
}
///
/// 第三层遍历,加速函数
///
///
private void flashTreeViewLeaf(TreeNode tr1)
{
foreach (TreeNode node in tr1.Nodes)
{
//查找树的叶子节点
if (node.Nodes.Count == 0)
{
addNodeLeaf(node);
}
else
{
flashTreeViewLeaf(node);
}
}
}
///
/// 添加叶子节点
///
///
private void addNodeLeaf(TreeNode node)
{
int pid = Convert.ToInt32(node.Tag);
string sql = "select typeID,typeName_zh from invtypes where marketGroupID="+pid;
SQLiteDataAdapter reader = new SQLiteDataAdapter(sql, conn);
DataTable dtLeaf = new DataTable();
reader.Fill(dtLeaf);
if (dtLeaf.Rows.Count > 0)
{
foreach(DataRow dr in dtLeaf.Rows)
{
TreeNode nodeleaf = new TreeNode();
nodeleaf.Text = dr[1].ToString();
nodeleaf.Tag = Convert.ToInt32(dr[0]);
node.Nodes.Add(nodeleaf);
}
}
}
private void setTreeView(TreeNode tr1, int parentId)
{
string sql;
if (parentId == 0)
sql = "select marketGroupID,marketGroupName_zh,parentGroupID from invmarketgroups where parentGroupID is null";
else
sql = "select marketGroupID,marketGroupName_zh,parentGroupID from invmarketgroups where parentGroupID=" + parentId;
SQLiteDataAdapter reader = new SQLiteDataAdapter(sql, conn);
DataTable dt = new DataTable();
reader.Fill(dt);
if (dt.Rows.Count > 0)
{
int pId = -1;
foreach (DataRow row in dt.Rows)
{
TreeNode node = new TreeNode();
node.Text = row[1].ToString();
node.Tag = Convert.ToInt32(row[0]);
if (row[2] is System.DBNull)
pId = 0;
else
pId = Convert.ToInt32(row[2]);
if (pId == 0)
{
//添加根节点
tr1.Nodes.Add(node);
}
else
{
//添加根节点之外的其他节点
RefreshChildNode(tr1, node, pId);
}
//查找以node为父节点的子节点
setTreeView(tr1, Convert.ToInt32(node.Tag));
}
}
}
//处理根节点的子节点
private void RefreshChildNode(TreeNode tr1, TreeNode treeNode, int parentId)
{
foreach (TreeNode node in tr1.Nodes)
{
if (Convert.ToInt32(node.Tag) == parentId)
{
node.Nodes.Add(treeNode);
return;
}else if (node.Nodes.Count > 0)
{
FindChildNode(node, treeNode, parentId);
}
}
}
//处理根节点的子节点的子节点
private void FindChildNode(TreeNode tNode, TreeNode treeNode, int parentId)
{
foreach (TreeNode node in tNode.Nodes)
{
if (Convert.ToInt32(node.Tag) == parentId)
{
node.Nodes.Add(treeNode);
return;
}else if (node.Nodes.Count > 0)
{
FindChildNode(node, treeNode, parentId);
}
}
}