在使用C#的过程中,难免会用到多线程,而用多线程之后,线程如何与界面交互则是一个非常头疼的问题。其实不仅仅是界面,一般情况下,我们往往需要获得线程的一些信息来确定线程的状态。比较好的方式是用委托实现,看例子:
class TestClass { //声明一个delegate(委托)类型:testDelegate,该类型可以搭载返回值为空,参数只有一个(long型)的方法。 public delegate void testDelegate(long i); //声明一个testDelegate类型的对象。该对象代表了返回值为空,参数只有一个(long型)的方法。它可以搭载N个方法。 public testDelegate mainThread; /// <summary> /// 测试方法 /// </summary> public void testFunction() { long i = 0; while(true) { i++; mainThread(i); //调用委托对象 Thread.Sleep(1000); //线程等待1000毫秒 } } }
winform界面代码:
1. /// <summary> 2. /// 按钮单击事件 3. /// </summary> 4. /// <param name="sender"></param> 5. /// <param name="e"></param> 6. private void button1_Click(object sender, EventArgs e) 7. { 8. //创建TestClass类的对象 9. TestClass testclass = new TestClass(); 10. 11. //在testclass对象的mainThread(委托)对象上搭载两个方法,在线程中调用mainThread对象时相当于调用了这两个方法。 12. testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1); 13. testclass.mainThread += new TestClass.testDelegate(refreshLabMessage2); 14. 15. //创建一个无参数的线程,这个线程执行TestClass类中的testFunction方法。 16. Thread testclassThread = new Thread(new ThreadStart(testclass.testFunction)); 17. //启动线程,启动之后线程才开始执行 18. testclassThread.Start(); 19. }
21. /// <summary> 22. /// 在界面上更新线程执行次数 23. /// </summary> 24. /// <param name="i"></param> 25. private void refreshLabMessage1(long i) 26. { 27. //判断该方法是否被主线程调用,也就是创建labMessage1控件的线程,当控件的InvokeRequired属性为ture时,说明是被主线程以外的线程调用。如果不加判断,会造成异常 28. if (this.labMessage1.InvokeRequired) 29. { 30. //再次创建一个TestClass类的对象 31. TestClass testclass = new TestClass(); 32. //为新对象的mainThread对象搭载方法 33. testclass.mainThread = new TestClass.testDelegate(refreshLabMessage1); 34. //this指窗体,在这调用窗体的Invoke方法,也就是用窗体的创建线程来执行mainThread对象委托的方法,再加上需要的参数(i) 35. this.Invoke(testclass.mainThread,new object[] {i}); 36. } 37. else 38. { 39. labMessage1.Text = i.ToString(); 40. } 41. } 42. 43. /// <summary> 44. /// 在界面上更新线程执行次数 45. /// </summary> 46. /// <param name="i"></param> 47. private void refreshLabMessage2(long i) 48. { 49. //同上 50. if (this.labMessage2.InvokeRequired) 51. { 52. //再次创建一个TestClass类的对象 53. TestClass testclass = new TestClass(); 54. //为新对象的mainThread对象搭载方法 55. testclass.mainThread = new TestClass.testDelegate(refreshLabMessage2); 56. //this指窗体,在这调用窗体的Invoke方法,也就是用窗体的创建线程来执行mainThread对象委托的方法,再加上需要的参数(i) 57. this.Invoke(testclass.mainThread, new object[] { i }); 58. } 59. else 60. { 61. labMessage2.Text = i.ToString(); 62. } 63. }
时间: 2024-12-24 08:21:11