winform 关于一个简单的多线程,求指点..类似进度条
首先说下,我从来没用过多线程,也没学过,对于多线程是个小白...
我想实现的是Form1 窗口点击一个按钮, 然后他的按钮事件里边有一个调用Form2的窗口,
把Form2这个窗口调用出来以后继续执行 From1按钮里边 调用Form2以后的代码。。。
就类似个进度条,我想用多线程就是想见识见识- -
不用多线程应该也可以实现把- - 我是个新手刚接触c#没几天
private void btnquery_Click(object sender, EventArgs e)
{
f = new Form2();//调用圆形进度条
f.Show(); //问下高手为什么直接点击按钮这个窗口不会显示啊?不显示就直接去执行数据库查询代码了
#region 判断空
if (radioButton1.Checked==false&&radioButton2.Checked==false)
{
//进了这两个 return 的话那个窗口就出来了..
MessageBox.Show("请选择限制条件.");
return;
}
if (textBox1.Text.Equals(""))
{
textBox1.Focus();
MessageBox.Show("请输入数量。");
return;
}
textBox3.Text = "";
#endregion
//查询数据库的数据放到datagridview
queryClick();
}
[解决办法]
贴一段异步线程响应的code...
class Program
{
//我是一个委托,可以指向任何传入两个整数并返回一个整数的方法,正所谓函数方法指针
public delegate int BinaryOp(int x, int y);
static int Add(int x, int y)
{
Console.WriteLine(" add() invoked on thread {0}.", Thread.CurrentThread.ManagedThreadId);
Thread.Sleep(5000);
return x + y;
}
static void Main(string[] args)
{
//---start
//Console.Write("****synch delegate review*****");
//Console.WriteLine("main() invoked on thread {0}", Thread.CurrentThread.ManagedThreadId);
//BinaryOp b = new BinaryOp(Add);
//int answer = b(10, 10);
//Console.WriteLine("doing more work in main()!");
//Console.WriteLine("10+10 is {0}", answer);
//Console.ReadLine();
//---end
Console.Write("****Async delegate invocation*****");
//主线程输出
Console.WriteLine("main() invoked on thread {0}", Thread.CurrentThread.ManagedThreadId);
//次线程输出
BinaryOp a = new BinaryOp(Add);
IAsyncResult iar = a.BeginInvoke(10, 10, null, null);
while (!iar.IsCompleted)
{
Console.Write("doing more works in main!");
Thread.Sleep(1000);
}
int answer = a.EndInvoke(iar);
Console.WriteLine("10+10 is {0}", answer);
Console.ReadLine();
}
}
[解决办法]
你应当将计算操作放入创建的线程,而不是将进度指示窗口放入。
你需要封装两个函数:
1.将数据查询的部分封装成函数,或者用你的
queryClick();
2.将操作进度表的部分在form2中封装个public的函数(如果你需要报告进度的话)
将调用form2的进度表组件的value属性的语句封装在一个public函数中,用于在背景线程中调用。
使用循环的等待进度表,跳过此步骤。
3.在Button_Click中
3.1.执行你输入检查的部分
#region 判断空
if (radioButton1.Checked==false&&radioButton2.Checked==false)
{
//进了这两个 return 的话那个窗口就出来了..
MessageBox.Show("请选择限制条件.");
return;
}
if (textBox1.Text.Equals(""))
{
textBox1.Focus();
MessageBox.Show("请输入数量。");
return;
}
textBox3.Text = "";
#endregion
3.2.如果检查通过,显示进度表
f.Show();
3.3.创建进程去执行计算的部分,如
Thread.Start(queryClick);
4.在queryClick中,如需调用form2的进度表组件的value属性,调用步骤2的函数。
这里有一个概念,就是跨线程访问窗口控件。(新建线程访问form2所在线程的form2的组件)
这是不被允许的,会引发不一致性,你需要使用f2.Invoke方法在form2所在的线程去执行操作。
此时,你需要一个指向函数的变量:委托变量
4.1.声明一个委托变量指代步骤2所创建的函数。
Action 委托变量=步骤2所创建的函数;
4.2在queryClick需要改变form2进度表的value属性时,通过在form2线程上调用含有调用属性代码的函数的委托实现。
f2.Invoke(委托变量);