一、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的更多相关文章

  1. .Net基础——程序集与CIL HttpClient封装方法 .Net Core 编码规范 C#中invoke和beginInvoke的使用 WebServeice 动态代理类

    .Net基础——程序集与CIL   1. 程序集和CIL: 程序集是由.NET语言的编译器接受源代码文件产生的输出文件,通常分为 exe和dll两类,其中exe包含Main入口方法可以双击执行,dll ...

  2. invoke和beginInvoke

    首先说下,invoke和begininvoke的使用有两种情况: 1. control中的invoke.begininvoke. 2. delegrate中的invoke.begininvoke. 这 ...

  3. Control的Invoke和BeginInvoke详解

    (一)Control的Invoke和BeginInvoke 我们要基于以下认识: (1)Control的Invoke和BeginInvoke与Delegate的Invoke和BeginInvoke是不 ...

  4. C#异步编程のWPF Invoke和BeginInvoke

    我们先看个简单的例子: private void Window_Loaded(object sender, RoutedEventArgs e) { Console.WriteLine("B ...

  5. 2019.03.26 读书笔记 关于 invoke与begininvoke

    invoke与begininvoke是同步委托和异步委托,但是有两种使用情况: 1. control中的invoke.begininvoke. 2. delegrate中的invoke.beginin ...

  6. Invoke 与 BeginInvoke的区别

    引用文章路径:https://www.cnblogs.com/lsgsanxiao/p/5523282.html invoke和begininvoke 区别 一直对invoke和begininvoke ...

  7. invoke和begininvoke 区别

    一直对invoke和begininvoke的使用和概念比较混乱,这两天看了些资料,对这两个的用法和原理有了些新的认识和理解. 首先说下,invoke和begininvoke的使用有两种情况: 1. c ...

  8. C#中Invoke 和 BeginInvoke 的区别

    Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...

  9. Dispatcher中Invoke与BeginInvoke

    [同步]Invoke Application.Current.Dispatcher.Invoke(AutoIncreaseNumber); [异步]BeginInvoke Application.Cu ...

随机推荐

  1. wireshark抓取本地回环及其问题

    一:The NPF driver isn't running 这个错误是因为没有开启NPF服务造成的. NPF即网络数据包过滤器(Netgroup Packet Filter,NPF)是Winpcap ...

  2. 使用自由软件Icarus Verilog Simulator进行仿真

    Icarus Verilog Simulator(http://iverilog.icarus.com/home)使用iverilog作为源代码编译器,编译生成vvp程序文本,使用vvp作为运行时引擎 ...

  3. C#一个FTP操作封装类FTPHelper

    参考了网上一些代码,作了一些调整优化. 001 using System; 002 using System.Collections.Generic; 003 using System.Linq; 0 ...

  4. 使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 )

    使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 ) DrawLayout这个自己定义的空间非经常见.qq,网易新闻.知乎等等,都有这样的效果,那这样的效果是如何实现的呢? ...

  5. Splunk的安装与使用

    一.简单介绍         Splunk 是机器数据的引擎.使用 Splunk 可收集.索引和利用全部应用程序.server和设备(物理.虚拟和云中)生成的高速移动型计算机数据 .从一个位置搜索并分 ...

  6. Android -- Fragment动画异常Unknown animation name: objectAnimator

    异常 Caused by: java.lang.RuntimeException: Unknown animation name: objectAnimator 异常代码 FragmentTransa ...

  7. Spark踩坑记:共享变量

    收录待用,修改转载已取得腾讯云授权 前言 前面总结的几篇spark踩坑博文中,我总结了自己在使用spark过程当中踩过的一些坑和经验.我们知道Spark是多机器集群部署的,分为Driver/Maste ...

  8. Android直播实现 Android端推流、播放

    最近想实现一个Android直播,但是对于这方面的资料都比较零碎,一开始是打算用ffmpeg来实现编码推流,在搜集资料期间,找到了几个强大的开源库,直接避免了jni的代码,集成后只用少量的java代码 ...

  9. [Node.js] Level 2 new. Event

    Chat Emitter We're going to create a custom chat EventEmitter. Create a new EventEmitter object and ...

  10. linux下mysql-5.5.15安装详细步骤

    linux下mysql-5.5.15安装详细步骤 注:该文档中用到的目录路径以及一些实际的值都是作为例子来用,具体的目录路径以各自安装时的环境为准 mysql运行时需要一个启动目录.一个安装目录和一个 ...