- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
C_多线程函数如何传参数和返回值
C# Delegate/委托 与多线程
Learning, by 木公.
?? 最近写到两个程序都用到了多线程,但是由于需要调用主线程UI,所以总是会出错,Google了一下,终于找到了使用Delegate(委托)的解决方法,现在贴出来存档并且分享:
??? 很多时候写windows程序都需要结合多线程,在.net中用如下得代码来创建并启动一个新的线程。
??? public void ThreadProc();
??? Thread thread = new Thread(new ThreadStart(ThreadProc));
??? thread.IsBackground = true;
??? thread.Start();
??? 但是很多时候,在新的线程中,我们需要与UI进行交互,在.net中不允许我们直接这样做。可以参考MSDN中的描述:??? “Windows 窗体”使用单线程单元 (STA) 模型,因为“Windows 窗体”基于本机 Win32 窗口,而 Win32 窗口从本质上而言是单元线程。STA 模型意味着可以在任何线程上创建窗口,但窗口一旦创建后就不能切换线程,并且对它的所有函数调用都必须在其创建线程上发生。除了 Windows 窗体之外,.NET Framework 中的类使用自由线程模型。??? STA 模型要求需从控件的非创建线程调用的控件上的任何方法必须被封送到(在其上执行)该控件的创建线程。基类 Control 为此目的提供了若干方法(Invoke、BeginInvoke 和 EndInvoke)。Invoke 生成同步方法调用;BeginInvoke 生成异步方法调用。??? Windows 窗体中的控件被绑定到特定的线程,不具备线程安全性。因此,如果从另一个线程调用控件的方法,那么必须使用控件的一个 Invoke 方法来将调用封送到适当的线程。??? 正如所看到的,我们必须调用Invoke方法,而BeginInvoke可以认为是Invoke的异步版本。调用方法如下:
public delegate void OutDelegate(string text);
??? public void OutText(string text)
??? {
???????? txt.AppendText(text);
???????? txt.AppendText( tn );
??? }
??? OutDelegate outdelegate = new OutDelegate( OutText );
??? this.BeginInvoke(outdelegate, new object[]{text});
??? 如果我们需要在另外一个线程里面对UI进行操作,我们需要一个类似OutText的函数,还需要一个该函数的委托delegate,当然,这里展示的是自定义的,.net中还有很多其他类型的委托,可以直接使用,不需要而外声明。例如:MethodInvoker和EventHandler,这两种类型委托的函数外观是固定的,MethodInvoker是void Function()类型的委托,而EventHandler是void Function(object, EventArgs)类型的委托,第一个不支持参数,第二中的参数类型和数量都是固定的,这两种委托可以很方便的调用,但是缺乏灵活性。请注意BeginInvoke前面的对象是this,也就是主线程。现在再介绍Control.InvokeRequired,Control是所有控件的基类,对于这个属性MSDN的描述是:??? 获取一个值,该值指示调用方在对控件进行方法调用时是否必须调用 Invoke 方法,因为调用方位于创建控件所在的线程以外的线程中。该属性可用于确定是否必须调用 Invoke 方法,当不知道什么线程拥有控件时这很有用。??? 也就是说通过判断InvokeRequired可以知道是否需要用委托来调用当前控件的一些方法,如此可以把OutText函数修改一下:
??? public delegate void OutDelegate(string text);
??? public void OutText(string text)
??? {
???????? if( txt.InvokeRequired )
???????? {
???????????? OutDelegate outdelegate = new OutDelegate( OutText );
???????????? this.BeginInvoke(outdelegate, new object[]{text});
???????????? r
文档评论(0)