首 页 网络编程
网页制作 图形图象 操作系统 冲浪宝典
软件教学 认证考试

网络安全 网络办公 行业资讯 评测对比
您当前位置:站长天空 -> 软件教学-> 文件管理
delegate 与 多线程-.NET教程,算法/线程
作者:网友供稿 点击:480
推荐
西部数码-全国虚拟主机10强!20余项虚拟主机管理功能,全国领先!第6代双线路虚拟主机,南北访问畅通无阻!可在线rar解压,自动数据恢复设置虚拟目录等.免费赠送访问统计,企业邮局.Cn域名注册10元/年,自助建站480元起,免费试用7天,满意再付款!P4主机租用799元/月.月付免压金
站内搜索
文章页数:[1] 
很多时候写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( "\t\n" );

}

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});

return;

}

txt.appendtext(text);

txt.appendtext( "\t\n" );

}

注意,这里的函数没有返回,如果有返回,需要调用invoke或者endinvoke来获得返回的结果,不要因为包装而丢失了返回值。如果调用没有完成,invoke和endinvoke都将会引起阻塞。

现在如果我有一个线程函数如下:

public void threadproc()

{

for(int i = 0; i < 5; i++)

{

outtext( i.tostring() );

thread.sleep(1000);

}

}

如果循环的次数很大,或者漏了thread.sleep(1000);,那么你的ui肯定会停止响应,想知道原因吗?看看begininvoke前面的对象,没错,就是this,也就是主线程,当你的主线程不停的调用outtext的时候,ui当然会停止响应。



与以前vc中创建一个新的线程需要调用afxbeginthread函数,该函数中第一个参数就是线程函数的地址,而第二个参数是一个类型为lpvoid的指针类型,这个参数将传递给线程函数。现在我们没有办法再使用这种方法来传递参数了。我们需要将传递给线程的参数和线程函数包装成一个单独的类,然后在这个类的构造函数中初始化该线程所需的参数,然后再将该实例的线程函数传递给thread类的构造函数。代码大致如下:

public class procclass

{

private string procparameter = "";

public procclass(string parameter)

{

procparameter = parameter;

}

public void threadproc()

{

}

}

procclass threadproc = new procclass("use thread class");

thread thread = new thread( new threadstart( threadproc.threadproc ) );

thread.isbackground = true;

thread.start();

就是这样,需要建立一个中间类来传递线程所需的参数。

那么如果我的线程又需要参数,又需要和ui进行交互的时候该怎么办呢?可以修改一下代码:

public class procclass

{

private string procparameter = "";

private form1.outdelegate delg = null;

public procclass(string parameter, form1.outdelegate delg)

{

procparameter = parameter;

this.delg = delg;

}

public void threadproc()

{

delg.begininvoke("use procclass.threadproc()", null, null);

}

}

procclass threadproc = new procclass("use thread class", new outdelegate(outtext));

thread thread = new thread( new threadstart( threadproc.threadproc ) );

thread.isbackground = true;

thread.start();

这里只是我的一些理解,如果有什么错误或者不当的地方,欢迎指出。


文章整理:站长天空 网址:http://www.z6688.com/
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

文章页数:[1] 


放大字体显示 缩小字体显示 打印文章 推荐给朋友
热门文章
·C#:ListBox的2个常用方法Add,Clear与Items的2个属性-.NET教程,C#语言
·java连接sqlserver实例-JSP教程,Java技巧及代码
·Hibernate下数据批量处理解决方案-JSP教程,数据库相关
·一种基于pwm的电压输出dac电路设计
·delegate 与 多线程-.NET教程,算法/线程
·java Logging API 使用-JSP教程,Java技巧及代码
·ORACLE中LOB字段的使用和维护-ASP教程,数据库相关
·ups功率因数越大越好吗
·.NET三层经典架构PetShop3.0分析连载一-.NET教程,.NET Framework
·ASP后门之终极伪装-ASP教程,ASP基础
最新文章
·windows vista系统隐藏的12个网络工具_windows vista
·网站赚钱应如何选择网站联盟?_网赚技巧
·建站一级攻略 从看完之后就开始_站长心得
·论坛建设9大定律和经验分享_站长心得
·dreamweaver制作复杂交换图像_dreamweaver教程
·让你google广告90%不是公益广告的方法_google推广
·ppc 广告与转换率息息相关_google推广
·中国个人网站——新经济中的非主流1_站长心得
·blog设计的7个趋势_站长心得
·2005岁末blog程序大评点_站长心得
相关主题
  • Delegate的实际应用。-.NET教程,Windows开发
  • Delegates in C# - an introduction(转:英文)-.NET教程,面向对象编程
  • 西部数码虚拟主机

    友情链接
    CNNIC 西部数码
    万网 自助建站
    虚拟主机 asp空间
    域名注册 域名
    域名申请 主页空间
    论坛空间 网站空间
    国际域名 虚拟空间
    空间租用 DDOS防火墙
    成都主机托管 四川主机托管
    主机租用 服务器租用
    网站目录 自助建站
    虚拟主机 网址大全
    软件下载
    自助链接
    虚拟主机资讯 特价虚拟主机
    版权申明:本站文章均来自网络,如有侵权,请联系我们,我们收到后立即删除,谢谢!
    关于我们:站长天空:专业提供最新的站长资讯、在线教程、虚拟主机权威评测、虚拟主机性能对比、网站制作教程,开发教程,站长工具。包括网页制作教程、冲浪宝典、编程参考、操作系统、软件教学、行业动态等。
    特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有。
    发表评论 打印  刷新     关闭