首页 [终稿]C 多线程函数如何传参数和返回值

[终稿]C 多线程函数如何传参数和返回值

举报
开通vip

[终稿]C 多线程函数如何传参数和返回值[终稿]C 多线程函数如何传参数和返回值 C#多线程函数如何传参数和返回值 提起多线程,不得不提起 委托(delegates)这个概念. 我理解的委托就是 具有 同样参数和返回值 的函数的集合. 比如 public delegate void MyDelegate(int arg); 就是这种形式的函数 void Myfuntion(int i); 的集合. 如何将一个函数加入 委托 的集合? MyDelegate dele = new MyDelegate(Myfuntion1); 再增加一个 d...

[终稿]C 多线程函数如何传参数和返回值
[终稿]C 多线程函数如何传参数和返回值 C#多线程函数如何传参数和返回值 提起多线程,不得不提起 委托(delegates)这个概念. 我理解的委托就是 具有 同样参数和返回值 的函数的集合. 比如 public delegate void MyDelegate(int arg); 就是这种形式的函数 void Myfuntion(int i); 的集合. 如何将一个函数加入 委托 的集合? MyDelegate dele = new MyDelegate(Myfuntion1); 再增加一个 dele += new MyDelegate(Myfuntion2); ... 委托函数 dele 就是 具有整数参数和空返回值的函数 Myfuntion1,2的集合. 调用这个委托函数 dele(1); 就是逐个调用 Myfuntion1,2,... 一般线程函数的声明和启动 Thread t = new Thread(new ThreadStart(MyFunction)); t.Start(); 正是调用了没有参数和返回值的 委托函数 ThreadStart 其中的参数MyFunction 是 这个委托函数中的一员. 很明显 这样无法传参数和返回值,那我们该怎么办? 答案 八年级地理上册填图题岩土工程勘察试题省略号的作用及举例应急救援安全知识车间5s试题及答案 就在委托 的BeginInvoke() 方法 快递客服问题件处理详细方法山木方法pdf计算方法pdf华与华方法下载八字理论方法下载 上, BeginInvoke() 也是(异步)启动一个新线程. 例如 MyDelegate dele = new MyDelegate (MyFunction); dele.BeginInvoke(10,"abcd"); void MyFunction(int count, string str); 可以实现参数的传递. 如何收集线程函数 的 返回值? 与 BeginInvoke 对应 有个 EndInvoke 方法,而且运行完毕返回 IAsyncResult 类型的返回值. 这样我们可以这样收集 线程函数的 返回值 MyDelegate dele = new MyDelegate (MyFunction); IAsyncResult ref = dele.BeginInvoke(10,"abcd"); ... int result = dele.EndInvoke(ref); <----收集 返回值 int MyFunction(int count, string str); <----带参数和返回值的 线程函数 提示:"线程间操作无效:从不是创建控件“XX”的线程访问它" 一般来说,直接在子线程中对窗体上的控件操作是会出现异常,这是由于子线程和运行窗体的线程是不同的空间,因此想要在子线程来操作窗体上的控件,是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法,其作用就是让子线程告诉窗体线程来完成相应的控件操作。 现在用一个用线程控制的进程条来说明,大致的步骤如下: 1( 创建Invoke函数,大致如下: /// /// Delegate function to be invoked by main thread /// private void InvokeFun() { if( prgBar.Value < 100 ) prgBar.Value = prgBar.Value + 1; } 2( 子线程入口函数: /// /// Thread function interface /// private void ThreadFun() { //Create invoke method by specific function MethodInvoker mi = new MethodInvoker( this.InvokeFun ); for( int i = 0; i < 100; i++ ) { this.BeginInvoke( mi ); Thread.Sleep( 100 ); } } 3( 创建子线程: Thread thdProcess = new Thread( new ThreadStart( ThreadFun ) ); thdProcess.Start(); 出现这个问 快递公司问题件快递公司问题件货款处理关于圆的周长面积重点题型关于解方程组的题及答案关于南海问题 主要是因为在线程方法中操作了界面上的控件..lstPrime.Items.Add() 可以这样改下.. //定义一个委托 public delegate void MyInvoke(string str); //定义一个操作界面的方法 private void UpdateUI(string str) { //增加项 this.lstPrime.Items.Add(str); } //在线程的方法中,即你的Generate方法.. //里面只要是涉及到Items.Add操作的都改成如下形式即可.. //比如lstPrime.Items.Add(2);改成: MyInvoke mi=new MyInvoke(UpdateUI); this.BeginInvoke(mi,new object[]{ "2 "}); =================================================================== ========= BeginInvoke与Invoke的含义[转载]BeginInvoke 方法真的是新开一个线程进行异步调用 吗, 参考以下代码: public delegate void treeinvoke(); private void UpdateTreeView() { MessageBox.Show(System.Threading.Thread.CurrentThread.Name); } private void button1_Click(object sender, System.EventArgs e) { System.Threading.Thread.CurrentThread.Name = "UIThread"; treeView1.BeginInvoke(new treeinvoke(UpdateTreeView)); } 看看运行结果,弹出的对话框中显示的是 UIThread,这说明 BeginInvoke 所调用的委托 根本就是在 UI 线程中执行的。 既然是在 UI 线程中执行,又何来“异步执行”一说呢, 我们再看看下面的代码: public delegate void treeinvoke(); private void UpdateTreeView() { MessageBox.Show(Thread.CurrentThread.Name); } private void button1_Click(object sender, System.EventArgs e) { Thread.CurrentThread.Name = "UIThread"; Thread th = new Thread(new ThreadStart(StartThread)); th.Start(); } private void StartThread() { Thread.CurrentThread.Name = "Work Thread"; treeView1.BeginInvoke(new treeinvoke(UpdateTreeView)); } 再看看运行结果,弹出的对话框中显示的还是 UIThread,这说明什么,这说明 BeginInvoke 方法所调用的委托无论如何都是在 UI 线程中执行的。 那 BeginInvoke 究竟有什么用呢, 在多线程编程中,我们经常要在工作线程中去更新界面显示,而在多线程中直接调用界面控件的方法是错误的做法,具体的原因可以在看完我的这篇之后看看这篇:在多线程中如何调用Winform,如果你是大牛的话就不要看我这篇了,直接看那篇吧,反正那篇文章我没怎么看懂。 Invoke 和 BeginInvoke 就是为了解决这个问题而出现的,使你在多线程中安全的更新界面显示。 正确的做法是将工作线程中涉及更新界面的代码封装为一个方法,通过 Invoke 或者 BeginInvoke 去调用,两者的区别就是一个导致工作线程等待,而另外一个则不会。 而所谓的“一面响应操作,一面添加节点”永远只能是相对的,使 UI 线程的负担不至于太大而以,因为界面的正确更新始终要通过 UI 线程去做,我们要做的事情是在工作线程中包揽大部分的运算,而将对纯粹的界面更新放到 UI 线程中去做,这样也就达到了减轻 UI 线程负担的目的了。 而在那段更新树节点的代码中,其实唯一起作用的代码是: System.Threading.Thread.Sleep(100);,它使 UI 线程有了处理界面消息的机会,其实 数码幽灵 将问题复杂化了,只要以下的代码就可以很好的工作了。 private void button1_Click_(object sender, System.EventArgs e) { TreeNode tn; for(int i=0;i<100000;i++) { tn=new TreeNode (i.ToString()); this.treeView1.Nodes[0].Nodes.Add(tn); if (i%100 == 0) Application.DoEvents(); } }
本文档为【[终稿]C 多线程函数如何传参数和返回值】,请使用软件OFFICE或WPS软件打开。作品中的文字与图均可以修改和编辑, 图片更改请在作品中右键图片并更换,文字修改请直接点击文字进行修改,也可以新增和删除文档中的内容。
该文档来自用户分享,如有侵权行为请发邮件ishare@vip.sina.com联系网站客服,我们会及时删除。
[版权声明] 本站所有资料为用户分享产生,若发现您的权利被侵害,请联系客服邮件isharekefu@iask.cn,我们尽快处理。
本作品所展示的图片、画像、字体、音乐的版权可能需版权方额外授权,请谨慎使用。
网站提供的党政主题相关内容(国旗、国徽、党徽..)目的在于配合国家政策宣传,仅限个人学习分享使用,禁止用于任何广告和商用目的。
下载需要: 免费 已有0 人下载
最新资料
资料动态
专题动态
is_279425
暂无简介~
格式:doc
大小:20KB
软件:Word
页数:0
分类:高中语文
上传时间:2017-12-02
浏览量:61