C#中的Invoke和BeginInvoke
一、Control#Invoke() 和Control#BeginInvoke()
在非UI线程中调用MessageBox.Show()结果是非模态对话框;
在UI线程中调用MessageBox.Show()结果是模态对话框。
也就是说,MessageBox的模态还是非模态控制的是它所在的那个线程!一旦使用MessageBox,它就阻塞了它所在的那个线程。
在非UI线程中调用System.Forms.Timer#Start方法不管用,在UI线程中才管用。
以上两个例子引出今日的主角:Control#Invoke()和Control#BeginInvoke()
- Invoke和BeginInvoke函数使得非UI线程可以方便地把任务放到UI线程中去执行
- 在UI线程中调用Invoke和BeginInvoke这两个函数是没有意义的,这两个函数只能在非UI线程中调用
因为它俩的作用就是非UI线程将任务交给UI线程去执行 - 这两个函数的区别是:Invoke会阻塞非UI线程;BeginInvoke不会阻塞非UI线程
在编程中,耗时的任务(比如IO,网络请求等)是不允许放在UI线程中的。这一点在一切界面编程中总是成立的。在桌面编程中,从没有库明确禁止耗时任务放在UI线程中。你可以把耗时的任务放在UI线程中,并没有错误,只是难受的是自己。而Android中明确规定UI线程中禁止网络请求,否则会抛出异常。
当耗时任务结束之后,通常需要更新界面,这时,Invoke和BeginInvoke这两个函数就派上大用了。
以上两个问题的解决方案:使用Invoke调用MessageBox.Show()和timer.Start().
this.Invoke(new Action(delegate{}));
二、委托的Invoke和BeginInvoke
string haha(string s) {
return s + s.Length;
}
delegate string h(string s);//定义一个函数指针类型
Haha() {
h ha = haha;
IAsyncResult res = ha.BeginInvoke("weidiao", null, null);
string ans = ha.EndInvoke(res);//此处会阻塞
Console.WriteLine(ans);
}
IAsyncResult.IsCompleted属性可以判断任务是否执行完毕。
IAsyncResult res = ha.BeginInvoke("weidiao", null, null);
while (res.IsCompleted == false) {
Console.Write("*");
Thread.Sleep(500);
}
string ans = ha.EndInvoke(res);
IAsyncResult.AsyncWaitHandle属性可以使当前线程(主调线程)等待一段时间。WaitOne的第一个参数表示要等待的毫秒数,在指定时间之内,WaitOne方法将一直等待,直到异步调用完成,并发出通知,WaitOne方法才返回true。当等待指定时间之后,异步调用仍未完成,WaitOne方法返回false,如果指定时间为0,表示不等待,如果为-1,表示永远等待,直到异步调用完成。
h ha = haha;
IAsyncResult res = ha.BeginInvoke("weidiao", null, null);
while (!res.AsyncWaitHandle.WaitOne(500)) {
Console.Write("*");
}
string ans = ha.EndInvoke(res);
Console.WriteLine(ans);
使用回调函数
using System;
using System.Threading;
using System.Windows.Forms;
class Haha {
string haha(string s) {
Thread.Sleep(3000);
return s + s.Length;
}
delegate string h(string s);
void callback(IAsyncResult res) {
Console.Write(ha.EndInvoke(res));
}
h ha ;
Haha() {
ha = haha;
IAsyncResult res = ha.BeginInvoke("haha", new AsyncCallback(callback), null);
}
static void Main() {
new Haha();
Application.Run(new Form());
}
}
C#中的Invoke和BeginInvoke的更多相关文章
- .Net基础——程序集与CIL HttpClient封装方法 .Net Core 编码规范 C#中invoke和beginInvoke的使用 WebServeice 动态代理类
.Net基础——程序集与CIL 1. 程序集和CIL: 程序集是由.NET语言的编译器接受源代码文件产生的输出文件,通常分为 exe和dll两类,其中exe包含Main入口方法可以双击执行,dll ...
- invoke和beginInvoke
首先说下,invoke和begininvoke的使用有两种情况: 1. control中的invoke.begininvoke. 2. delegrate中的invoke.begininvoke. 这 ...
- Control的Invoke和BeginInvoke详解
(一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...
- C#异步编程のWPF Invoke和BeginInvoke
我们先看个简单的例子: private void Window_Loaded(object sender, RoutedEventArgs e) { Console.WriteLine("B ...
- 2019.03.26 读书笔记 关于 invoke与begininvoke
invoke与begininvoke是同步委托和异步委托,但是有两种使用情况: 1. control中的invoke.begininvoke. 2. delegrate中的invoke.beginin ...
- Invoke 与 BeginInvoke的区别
引用文章路径:https://www.cnblogs.com/lsgsanxiao/p/5523282.html invoke和begininvoke 区别 一直对invoke和begininvoke ...
- invoke和begininvoke 区别
一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解. 首先说下,invoke和begininvoke的使用有两种情况: 1. c ...
- C#中Invoke 和 BeginInvoke 的区别
Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...
- Dispatcher中Invoke与BeginInvoke
[同步]Invoke Application.Current.Dispatcher.Invoke(AutoIncreaseNumber); [异步]BeginInvoke Application.Cu ...
随机推荐
- Eclipse中运行Tomcat遇到的内存溢出错误
使用Eclipse(版本Indigo 3.7)调试Java项目的时候,遇到了下面的错误: Exception in thread "main" Java.lang.OutOfMem ...
- Latex初学者入门(三)-- 用BibTeX生成参考文献
昨boss要往期Elsevier 刊投文章,距上次排版貌似过了好久,生疏了不少,翻出以前的写的一些笔记再复习复习. 不过这次好多了,仅仅是改个格式,原始的文章已经用latex编写过了(个人感觉最头疼的 ...
- 第十一章 企业项目开发--消息队列activemq
注意:本章代码基于 第十章 企业项目开发--分布式缓存Redis(2) 代码的github地址:https://github.com/zhaojigang/ssmm0 消息队列是分布式系统中实现RPC ...
- iOS开发-Xcode入门ObjC程序
元旦三天假跟妹子冷战一天半,剩下的半天觉得无聊,可以写点东西,折腾了下xCode 6.1,虽然iPhone6比较丑,但是不影响IOS在高端机上面的地位,ObjC是扩充C的面向对象编程语言.主要使用于M ...
- android.net.Uri 简介 API
android.net.Uri 简介 public abstract class android.net.Uri extends Object implements Parcelable, Compa ...
- 网络结构设计——负载均衡之LVS学习笔记(二)
LVS按个人理解的说就是将一台Linux服务器当作路由器等功能的技术.LVS---Linux虚拟服务器. LVS实现了三种IP负载均衡技术VS/NAT.VS/TUN.VS/DR. 今天简单分享一下我在 ...
- 怎样在Ubuntu中修改默认程序
这个新手指南会向你展示如何在 Ubuntu Linux 中修改默认程序.对于我来说,安装 VLC 多媒体播放器是安装完 Ubuntu 16.04 该做的事中最先做的几件事之一.为了能够使我双击一个视频 ...
- DockPanel 类
DockPanel 类 .NET Framework 4.5 其他版本 此主题尚未评级 - 评价此主题 定义您可水平或垂直排列子元素的区域,互相. 继承层次结构 System.Obje ...
- UE如何将某些字符替换成换行
如下所示,我想要在所有;后面加个回车 就把;替换成;^r^n 效果如下所示
- C# 64位系统调用32位DLL异常解决办法(异常来自HRESULT :0x8007007E)
解决办法如下 1.在IDE中将目标平台设置成x86(VS是在项目的属性->生成->目标平台) 2.如果DLL中调用了其他的DLL,需要将其他的DLL一同编译 3.有时DLL生成时会依赖于I ...