当前位置: 首页 > 编程日记 > 正文

实现等待窗体的几种方式

实现等待窗体的几种方式:

下面说明了五种可以实现等待窗体的方式,其中三种给出了代码。

准备资料

安全访问控件成员

为了保证在创建控件的线程上调用控件成员,用下面的方式封装控件的属性、方法、其他自定义成员的访问。

: winWordControl.LoadDocument()封装为:

delegate void VoidDelegate();  

private void LoadDocument()

        {

            if (InvokeRequired)

            {

                Invoke(new VoidDelegate(LoadDocument));

                return;

            }

            this.winWordControl.LoadDocument();      

        }

下面的代码封装了winWordControl.OpenMode=Opration

private delegate void OpenModeDelegate(Operation op);

        private void OpenMode(Operation value)

        {

            if (InvokeRequired)

            {

                Invoke(new OpenModeDelegate(OpenMode), new object[] { value });

                return;

            }

            winWordControl.OpenMode = value;

      

        }

这些封装保证了对控件成员的访问在任何线程都是安全的。

例子说明

例子假定有三个窗体:

MainForm

Preview preview;//Preview 是在此线程创建

Privite void SomeMethod()

{

Thread wordInit = new Thread(new ThreadStart(preview.InitWordDocControl));

     wordInit.Start();

}

第二个窗体

PreviewForm

WinWordControl winWordControl = new WinWordControl();

Private void InitWordDocControl()

{

     //执行初始化加载word、实现延迟窗体

     //TODO

}

第三个窗体

WaitForm:提示信息

实现方式

InitWordDocControl为了在加载word时不出现假死,必须开启新线程。
由于用到了非托管资源,最简单的方式是把托管资源(WaitForm)放在工作线程,线程结束,窗体会自动销毁,不用自己写清理代码。


第一种:ShowDialog

ShowDialog自动阻塞当前线程,这使它成为最优的解决方式。

Private void InitWordDocControl()

{

     Thread thread = new Thread(new ThreadStart(Waiting));

     thread.Start();

     LoadDocument();

thread.Abort();//销毁线程,自动回收托管资源

}

  private void Waiting()

        {

          //局部变量,在此线程创建,可以直接操作其成员

            Wait FormWait = new Wait();

            FormWait.StartPosition = FormStartPosition.CenterScreen;

            FormWait.ShowDialog(); //线程等待         

        }

private void LoadDocument()

        {

            if (InvokeRequired)

            {

                Invoke(new VoidDelegate(LoadDocument));

                return;

            }

            this.winWordControl.LoadDocument();       

        }

最简单的解决方式,利用了托管资源的优势和ShowDialog本身的特性。

第二种:Show

如果简单的修改Waiting为:

  private void Waiting()

        {

           Wait FormWait = new Wait();

            FormWait.StartPosition = FormStartPosition.CenterScreen;

            FormWait.Show();       //窗体立即被销毁 

        }

窗体肯定会一闪而过,因为FormWait是局部变量,出了方法体就会被回收。

因此要改成下面的形式:

首先把局部变量改为字段,让他在加载类型时分配内存。其次,做如此修改后,创建Wait的线程就变成了创建Preview的线程,这样就不能直接修改此窗体属性,必须用Invoke

private void Waiting()

        {

//下面的调用都是线程安全的,内部都会判断是否是创建线程,不是会调用Invoke

            CreateWait();

            SetFormStartPosition(FormStartPosition.CenterScreen);

            ShowWait();

        }

修改:

Private void InitWordDocControl()

{

     Thread thread = new Thread(new ThreadStart(Waiting));

     thread.Start();

     thread.Join();//阻塞调用线程,让其先执行完show

     LoadDocument();

}

修改LoadDocument()

private void LoadDocument()

        {

            if (InvokeRequired)

            {

                Invoke(new VoidDelegate(LoadDocument));

                return;

            }

            this.winWordControl.LoadDocument(); 

            CloseWait(); //释放资源,线程自动销毁。注意也要使用线程安全的形式。    

        }

第三种:异步委托

本质上通过线程池中的线程执行委托方法,仍然是线程问题。但是可以用show和异步委托结合,简单的实现等待。可以看出代码比上面实现简单许多。

首先这次把加载word放到新线程中,而WaitForm在原线程。

修改:

Private void InitWordDocControl()

{

     Waiting();

     MethodInvoker mi = new MethodInvoker(LoadDocument);

     mi.BeginInvoke(AsyncCallClose,null);//执行完委托方法,执行AsyncCallClose来关闭等待窗体。

}

private void AsyncCallClose(IAsyncResult ar)

        {

            FormWait.Close();             

        }

 MethodInvoker,只是系统定义的委托,提供些许便利,更好的方式是自己定义如:

delegate void VoidDelegate();VoidDelegate MethodInvoker是等价的。

在这种实现中发现了下面的问题:控件成员可以不在创建控件的线程中使用!!如FormWait.Close();调用此语句的是线程池中的线程,而FormWait是在另外的线程中创建。不知道是什么原因??按照必须在创建控件线程调用成员,则会抛异常。按照许多资料,这种情况也是非法调用,但在此却没有问题?!

第四种:信号量

以前没有用过线程,遇到这个问题,首先想到的是信号量来控制线程通信。可以参考后面的资料或者我以前的文章:

http://www.cnblogs.com/bluewater/archive/2006/08/14/476720.html

第五种:Timer

本质也是线程,有同学说,他一直在VB中用Timer来模拟线程来控制时间片。应该也能实现等待窗体。

在此使用线程,主要是为了有好的用户体验,避免假死。

第一次使用线程,查了许多资料,但仍然有个问题没有解决,再写一遍,希望有人指点原因。

在这种实现中发现了下面的问题:控件成员可以不在创建控件的线程中使用!!如FormWait.Close();调用此语句的是线程池中的线程,而FormWait是在另外的线程中创建。不知道是什么原因??按照必须在创建控件线程调用成员,则会抛异常。按照许多资料,这种情况也是非法调用,但在此却没有问题?!


资料:

一系列关于线程的入门文章,非常好

http://www.yoda.arachsys.com/csharp/threads/parameters.shtml

关于UI

http://msdn.microsoft.com/msdnmag/issues/03/02/Multithreading/

关于Timer

http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET/default.aspx

相关文章:

GitHub宝藏项目标星1.6w+,编程新手有福了

作者 | Rocky0429来源 | Python空间(ID: Devtogether)特别惭愧的是,虽然我很早就知道 GitHub,但是学会逛 GitHub 的时间特别晚。当时一方面是因为菜,看着这种全是英文的东西难受,不知道该怎么去玩&#xff…

VC下提前注入进程的一些方法3——修改程序入口点

前两节中介绍了通过远线程进行注入的方法。现在换一种方法——修改进程入口点。(转载请指明出处) 在PE文件中,其中有个字段标识程序入口点位置。我们通过这个字段,到达程序入口点。PE文件的结构我这儿不讨论(我会在之后…

如何产生签名applet能让applet能够访问本地资源

2019独角兽企业重金招聘Python工程师标准>>> 如何产生签名applet,以使applet能够访问本地资源? 在jdk1.1中,可以使用javakey命令来产生公钥,私钥,证书和签名的jar文件,详细资料请参考: http://java.sun.com/security/usingJavakey.html而java 2对签名机制做了比较大…

VC提前注入.net软件的方法

在之前几节介绍了各种注入方法,但是这些方法存在一些缺陷——对.net程序注入无效。(转载请指明出处) 这个可以理解,.net程序的代码不是汇编,而是微软自定义的IL中间语言。.net CLR如同虚拟机,解析并执行这些…

活动推荐:语音和语言技术在自然交互中的实践沙龙

智能语音技术已经渗透进家居生活、车载、金融服务等日常生活场景,在很大程度上解放了人们的双手和眼睛,语音交互成为连接人与信息/服务的新入口。根据IDC预测,国内对话式人工智能市场规模将在2022年达到78亿元。如何提供便捷、高效、高可用的…

JS字符串 window.open() window.opener window.name window对象总结

晚上总结了一下,发上来分享:字符串 window.open() window.opener window.name window对象等的一点总结 http://download1.csdn.net/down3/20070614/14012050509.rar

dedecms /member/reg_new.php SQL Injection Vul

catalog 1. 漏洞描述 2. 漏洞触发条件 3. 漏洞影响范围 4. 漏洞代码分析 5. 防御方法 6. 攻防思考 1. 漏洞描述 Dedecms会员中心注入漏洞 2. 漏洞触发条件 http://127.0.0.1/dedecms5.5/member/reg_new.php?dopostregbase&step1&mtype%B8%F6%C8%CB&mt…

VC下通过进程ID获取进程镜像文件路径的方法及其存在的缺陷

工作中经常会遇到通过进程ID获取进程镜像文件或者其他模块的路径的需求。(转载请指明出处)网上关于方案大致存在两种方案: OpenProcess->GetModuleFileNameOpenProcess->EnumProcessModules->GetModuleFileNameEx我试验了下&#x…

腾讯云100亿元目标达成,发阳光普照奖iPhone 11 Pro,你酸了吗?

12 月 19 日,鹅厂腾讯发钱的消息又像往年一样引来了一群柠檬精。除了微信支付团队获得 2 亿元奖金的消息之外,一张腾讯云团队每个员工奖励一部 iPhone 11 Pro 的 H5 页面截图也不断地轰炸着朋友圈。原来这张图说的是腾讯云在 Q3 已完成 2019 年全年 100 …

分享一个python cookbook的在线教程地址

分享一个python cookbook的在线教程地址:http://python3-cookbook.readthedocs.org/zh_CN/latest/翻译者:熊能转载于:https://blog.51cto.com/verdureorange/1653514

优化系统后VS启动不了问题的一种解决方案

本文只讨论使用第三方软件优化系统后,或者您主动禁止服务后导致VS不能启动的问题。(转载请指明出处) 记得大概是08年时,我使用一些软件对电脑启动项做了优化。后来打开VS2005时,发现VS2005会一直保持在“载入界面”,当时十分懊恼&…

懂数学的程序员能有多吃香?这是我听过最好的答案丨颠覆认知

懂数学的程序员能有多吃香?关于这个问题,我想每个程序员心中都有自己的答案。之前在网上看到一个很有意思的答案说:我是在做了2年的开发之后,才真正认识到数学对于程序员的重要性,开始系统的学习数学。理由无它&#x…

基于OpenCasCade的程序发布问题

基于OpenCasCade二次开发了一个程序,想采用简单的copy的发布(部署)方式。 但在发布时遇到了很多问题。总结一下。 首先将所有所需的dll拷贝到了执行目录下,然后将程序copy到一台未安装OpenCasCade的机器上运行出错,信…

Unity3D移植到自己的Android程序

用Unity3D开发需要把动画效果移植到现有的APP上面。Unity for Android 比较特殊,Unity for IOS 打包是将XCODE工程直接交给开发者,开发者可以在工程的基础上继续添加新的视图,最后由开发者自行打包生成IPA包,发布程序。而Unity fo…

一种注册表沙箱的思路、实现

从今年4月份开始,我接触到一个沙箱项目。该项目的需求要求我们的沙箱具有良好的安全性和兼容性。当时我们研究了SandBoxIE和360的沙箱,基本确定通过“重定向”思路来实现这款沙箱。而我主要负责研究注册表这块。(转载请指明出处)在…

PyTorch实现L2和L1正则化的方法 | CSDN博文精选

作者 | pan_jinquan来源 | CSDN博文精选目录1.torch.optim优化器实现L2正则化2.如何判断正则化作用了模型?2.1未加入正则化loss和Accuracy2.1加入正则化loss和Accuracy2.3正则化说明3.自定义正则化的方法3.1自定义正则化Regularization类3.2Regularization使用方法4…

构建插件式的应用程序框架(六)----通讯机制(ZT)

前天发了构建插件式的应用程序框架(五)----管理插件这篇文章,有几个朋友在回复中希望了解插件之间是如何通讯的。这个系列的文章写到这里,也该谈谈这个问题了,毕竟已经有了插件管理。不知道大家…

【翻译】将Ext JS Grid转换为Excel表格

原文:Converting an Ext 5 Grid to Excel Spreadsheet稍微迟来的礼物——Ext JS Grid转为Excel代码,现在支持Ext JS 5!功能包括: - 支持分组 - 数字的处理 VS 字符串数据类型 - 对于不支持客户端下载的浏览器会提交回服务器Enjoy&…

AI研究过于集中狭隘,我们是不是该反思了?

作者 | Sergii Shelpuk译者 | 陆离编辑 | 夕颜出品 | AI科技大本营(ID: rgznai100)【导读】2019年是AI领域更加冷静的一年,少了些喧嚣和泡沫,大浪淘沙留下的是经过检验的真正的AI研究者、实践者。但是你也许没有发现,本…

上周回顾:微软与苹果比赛谁更“不安全”

每个月的第二周应该是微软例行发布补丁的日子,本周也不例外,微软如定期新闻发布会一样公布了自己的安全公告。这本来已经成了例如51CTO.com这样关注企业网络安全的媒体重要的素材,不过没想到的是本周苹果偏要抢这个风头……热点一&#xff1a…

一种注册表沙箱的思路、实现——注册表的一些基础知识

要做注册表沙箱,就必须要了解部分注册表知识。而注册表的知识很多,本文主要讲述如何在win32系统是上识别注册表映射的。(转载请指明出处) 在我的xp 32bit系统上,WinR regedit之后打开注册表管理器。我们可以看到如下主…

bzoj 2565: 最长双回文串 manacher算法

2565: 最长双回文串 Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://www.lydsy.com/JudgeOnline/problem.php?id2565 Description 顺序和逆序读起来完全一样的串叫做回文串。比如acbca是回文串,而abc不是(abc的顺序为“abc”,逆…

44岁的微软如何刷新未来?

整理 | 伍杏玲出品 | AI科技大本营(ID:rgznai100)在当今的“云”时代,很多企业在多个云计算平台部署应用,且需要统一管理和保护应用。在微软Ignite 2019 大会上,为了让企业轻松地在任何类型的基础设施平台上…

一种注册表沙箱的思路、实现——Hook Nt函数

Nt函数是在Ring3层最底层的函数了,选择此类函数进行Hook,是为了提高绕过门槛。我的Hook方案使用的是微软的Detours。(转载请指明出处)Detours的Hook和反Hook的写入如下: DetourTransactionBegin(); DetourUpdateThread…

浅析Struts 体系结构与工作原理(图)

Struts 体系结构是目前基于java的 web系统设计中广泛使用的mvc构架。基本概念    Struts是Apache 基金会Jakarta 项目组的一个Open Source 项目,它采用模型-视图-控制器(Model-View- Controller,简称MVC)模式,能够…

2015第22周一Web性能测试工具及IE扩展区别

在高性能web测试工具推荐http://www.jb51.net/article/23034.htm中发现了dynaTrace 感觉很不错,不但可以检测资源加载瀑布图,而且还能监控页面呈现时间,CPU花销,JS分析和执行时间,CSS解析时间的等。http://www.ibm.com…

一种注册表沙箱的思路、实现——研究Reactos中注册表函数的实现1

因为我们沙箱注入了一个DLL到了目标进程,并且Hook了一系列NtXX(NtOpenKey)函数,所以我们在注入的代码中是不能使用RegXX(RegOpenKey等)这类函数的。因为RegXX系列函数在底层使用了NtXX系列函数,如果在注入DLL执行Hook后的逻辑中使用了RegXX系…

面试大厂背怼!这都搞不定,你只能做“搬运工”!

每一个面试过大厂的程序员似乎总会有种种困境:毕业季参加大厂校招面试,我本以为做过一些真实项目就不错了,没想到根本没问什么项目,都是基础知识,数学、算法,然而平时只喜欢学程序设计。小公司工作3年&…

net程序架构开发

< DOCTYPE html PUBLIC -WCDTD XHTML StrictEN httpwwwworgTRxhtmlDTDxhtml-strictdtd> 程序架构,功能的划分: 数据库(包括存储过程) 数据访问(包括Microsoft Application Blocks for .NET的2.0版) 数据结构(等价于强类型DataSet) 业务逻辑层 业务表现层 数据库:不用说…

Java面向对象学习笔记 -- 6(内部类、Timer)

1. 内部类内部类就是在一个类的内部定义的类&#xff0c;有&#xff1a;静态内部类、成员内部类&#xff0c;局部内部类、匿名内部类。-1) 静态内部类&#xff1a;使用static修饰&#xff0c;声明在类体中&#xff0c; 静态内部类中可以访问外部类的静态成员&#xff0c;开发很…