今天我想操作二十万左右数据,进行整体的修改,当然是进行了相当复杂运算的,如果单线程那就只有晚上执行了,但是急需看到结果,慢慢开始了今天的主题,多线程编程,个人不建议线程太多,我这里设置的 private readonly int thread = 10;//进程数 ;
先把效果图附上,
确保是真实有效的,并不是忽悠。
接下来上代码了。
delegate void SetTextCallback(System.Windows.Forms.Control ct, string text);
delegate void SetTextCallback2(System.Windows.Forms.Control ct, int text);
delegate void SetTextCallback3(System.Windows.Forms.Control ct, bool falt);
#region 参数
private readonly int thread = 10;//进程数
private int i = 0;//报告进度的累加器
private int sumcount = 0;
Thread[] threadk;
private readonly static object locker = new object();
#endregion
/// <summary>
/// 开始执行
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
ChangeThreadeds();
}
#region 后台控制UI
/// <summary>
/// 显示执行的百分比
/// </summary>
/// <param name="ct"></param>
/// <param name="text"></param>
public void SetText(System.Windows.Forms.Control ct, string text)
{
//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
while (!ct.IsHandleCreated)
{
;
}
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (ct.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText);
this.Invoke(d, new object[] { ct, text });
}
else
{
ct.Text = text;
}
}
/// <summary>
/// 执行按钮是否可以与用户交互
/// </summary>
/// <param name="ct"></param>
/// <param name="falt"></param>
public void SetText2(System.Windows.Forms.Control ct, bool falt)
{
//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
while (!ct.IsHandleCreated)
{
;
}
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (ct.InvokeRequired)
{
SetTextCallback3 d = new SetTextCallback3(SetText2);
this.Invoke(d, new object[] { ct, falt });
}
else
{
(ct as Button).Enabled = falt;
}
}
/// <summary>
/// 显示进度条
/// </summary>
/// <param name="ct"></param>
/// <param name="text"></param>
public void SetText3(System.Windows.Forms.Control ct, int text)
{
//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
while (!ct.IsHandleCreated)
{
;
}
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (ct.InvokeRequired)
{
SetTextCallback2 d = new SetTextCallback2(SetText3);
this.Invoke(d, new object[] { ct, text });
}
else
{
(ct as ProgressBar).Value = text;
}
}
public void SetText4(System.Windows.Forms.Control ct, string text)
{
//在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke 解决
while (!ct.IsHandleCreated)
{
;
}
// InvokeRequired需要比较调用线程ID和创建线程ID
// 如果它们不相同则返回true
if (ct.InvokeRequired)
{
SetTextCallback d = new SetTextCallback(SetText4);
this.Invoke(d, new object[] { ct, text });
}
else
{
ct.Text += text;
}
}
#endregion
#region 创建多线程
/// <summary>
/// 创建并且启动多条线程
/// </summary>
void ChangeThreadeds()
{
SetText2(button1, false);
sumcount = 1000; //ds.Tables.Count > 0 ? ds.Tables[0].Rows.Count : 0;
threadk = new Thread[thread];
for (int j = 0; j < thread; j++)
{
threadk[j] = new Thread(new ThreadStart(updateIvaddr));
threadk[j].Name = "线程" + j.ToString();
threadk[j].Start();
}
}
/// <summary>
/// 修改方法
/// </summary>
/// <param name="mo"></param>
void updateIvaddr()
{
while (i<1000)
{
lock (locker)//记得加锁噢
{
if(i>1000) //记得是双重判断,不然会出问题,为什么你知道的。
break;
i++;
zhixing(dr);
SetText(label1, ((i * 100) / sumcount).ToString() + "%");
SetText3(progressBar1, (i * 100) / sumcount);
}
}
SetText2(button1, true);
}
/// <summary>
/// 执行整体方法
/// </summary>
void zhixing(DataRow dd)
{
SetText4(richTextBox1, Thread.CurrentThread.ManagedThreadId.ToString() + "=>" + Thread.CurrentThread.Name.ToString() + "\n");
}
#endregion
代码奉献完毕,具体为什么大家一看就明白我相信,不是我们不会,而是我们没有实践,实践以后,相信我们是最棒的。
注:此代码是我程序用到,经过改变,为初学者提供的,为原创,请勿大家转载。谢谢