委托和多线程(一)

摘要:
参数n);操作委托实例=;委托实例(参数);谓词<T>表示定义一组条件,并确定指定的对象是否满足这些条件。返回值始终是bool类型声明的原型:public delegateboolPredicate<inT>,因为它很奇怪;这里有一个示例:1 public toolMatch2{3return val>60;4}56 Predicate<int>t=newPredicate>int>//定义比较委托7int〔〕arr={13,45,26,98,35,72,24};8intfirst=阵列。查找;//在数组中找到大于60的第一个元素,然后依次引入它:1.Invoke2、BeginInvoke、EndInvoke3、Thread4、线程池5、线程同步6、死锁7、线程同步的几种方法8.访问GUI组件Invoke:Control。在线程中调用方法:在具有此控件的基本窗口句柄的线程上执行指定的委托。

         定义:委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通俗的说,委托是一个可以引用方法的对象,当创建一个委托,也就创建一个引用方法的对象,进而就可以调用那个方法,即委托可以调用它所指的方法。

委托的试用步骤:

1、定义委托:权限修饰符   delegate   返回值     委托名 (参数);

2、声明委托:  委托名 委托对象;

3、将对象与委方法绑定(可以绑定一个方法或者多个方法): 委托对象  = new 委托名(需要绑定的方法名称);

4、使用委托调用方法:委托实例名(参数);

Ps:1、委托和委托绑定的方法需要相同的参数(参数类型和个数都要相同)和返回值;

        2、委托可以调用多个方法,委托对象可以维护可调用方法的列表;即多路广播,简称:多播;

        3、使用+= 添加绑定方法,-=释放绑定方法;delegate委托可以不带参数,支持最大23个参数;可以没有返回值,也可以带返回值;

委托其中常见的写法有:

1、实例化委托并调用:委托名  委托实例 = new 委托名(委托方法);委托实例(参数);

2、实例化委托并调用 简写委托名  委托实例 = 委托的方法 ;委托实例(参数);

3、实例化委托并调用 匿名委托:委托名   委托实例 = delegate(参数){待调用的方法体};委托名(参数);

4、实例化委托并调用 lambda表达式写法:委托名  委托实例 = ((参数1,参数2,参数3,参数4,...参数n)=>{待调用的方法体});委托实例(参数1,参数2,参数3,...参数n);

5、在.NET 2.0开始 ,出现Func<in T,out TResult> 和Action<in T>

     Func至少0个参数,至多16个参数,必须有返回值

     Action至少0个参数,至多16个参数,无返回值。

     Func<参数1,参数2,...参数n,返回值> 委托实例 = ((参数1,参数2,。。。参数n)=>{带返回值的方法体});

     返回值 = 委托实例(参数1,参数2,。。。参数n);

     Action<参数> 委托实例 = ((参数)=>{待执行的方法体});委托实例(参数);

     Predicate<T>表示定义一组条件并确定指定对象是否符合这些条件的方法,返回值始终为bool类型

      申明的原型:  public delegate bool Predicate<in T>(T obj)  由于比较陌生;所以下面给一个事例:

      

1 public bool Match(int val)
2 {
3     return val > 60;
4 }
5     
6 Predicate<int> t = new Predicate<int>(Match);   //定义一个比较委托
7 int[] arr = { 13, 45, 26, 98, 3, 56, 72, 24 };            
8 int first = Array.Find(arr, t);                 //找到数组中大于60的第一个元素

  下面陆续介绍:

1、Invoke

2、BeginInvoke,EndInvoke

3、Thread

4、线程池

5、线程同步

6、死锁

7、线程同步的几种方法

8、在线程中访问GUI组件

Invoke:

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

      Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句柄所在线程上异步执行指定委托。

 msdn说明:

      控件上的大多数方法只能从创建控件的线程调用。 如果已经创建控件的句柄,则除了 InvokeRequired 属性以外,控件上还有四个可以从任何线程上安全调用的方法,它们是:InvokeBeginInvokeEndInvoke 和 CreateGraphics。 在后台线程上创建控件的句柄之前调用 CreateGraphics 可能会导致非法的跨线程调用。 对于所有其他方法调用,则应使用调用 (invoke) 方法之一封送对控件的线程的调用。 调用方法始终在控件的线程上调用自己的回调。

      主线程调用Invoke:

1       public void TestInvoke()
2         {
3             listBox1.Items.Add("----Add------
");
4             listBox1.Invoke(new Action(() => { listBox1.Items.Add("Incoke"); }));
5             Thread.Sleep(1000);
6             listBox1.Items.Add("---End-----");
7         }

     主线程调用BeginInvoke:

1        public void TestInvoke()
2         {
3             listBox1.Items.Add("----Add------
");
4             var b = listBox1.BeginInvoke(new Action(() => { listBox1.Items.Add("BrginInvoke"); }));
5             Thread.Sleep(1000);
6             listBox1.Items.Add("---End-----");
7         }

只有当调用BeginInvoke的线程结束后,才执行它的内容。

不过有两种情况下,它会马上执行;1、使用EndInvoke,检索由传递的 IAsyncResult 表示的异步操作的返回值。2、同一个控件调用Invoke时,会马上执行先前的BeginInvoke

1、

 1  public void TestInvoke()
 2         {
 3             listBox1.Items.Add("----Add------
");
 4             var b = listBox1.BeginInvoke(new Action(() =>
 5             {
 6                 Thread.Sleep(1000);
 7                 listBox1.Items.Add("BrginInvoke");
 8             }));
 9             listBox1.EndInvoke(b);
10             listBox1.Items.Add("---End-----");
11         }

2.

 1  private void TestBeginInvokeInvoke()
 2         {
 3             listBox1.Items.Add("--begin--");
 4             listBox1.BeginInvoke(new Action(() =>
 5                 {
 6                     Thread.Sleep(1000);
 7                     listBox1.Items.Add("BeginInvoke");
 8                 }));
 9             listBox1.Invoke(new Action(() =>
10                 {
11                     listBox1.Items.Add("Invoke");
12                 }));
13             listBox1.Items.Add("--end--");
14         }

 注:在主线程中直接调用Invoke、BeginInvoke、EndInvoke都会造成阻塞。所以应该利用副线程(支线线程)调用

  • Invoke的委托在主线程中执行
  • Invoke在支线程中调用也会阻塞主线程
  • Invoke还会阻塞支线程

免责声明:文章转载自《委托和多线程(一)》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇https 单向认证和双向认证配置Window API 之 PostMessage (消息投递)下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Java并发实现线程阻塞原语LockSupport

LockSupport 和 CAS 是Java并发包中很多并发工具控制机制的基础,它们底层其实都是依赖Unsafe实现。LockSupport是用来创建锁和其他同步类的基本线程阻塞原语。 1、LockSupport原理 LockSupport是只有静态方法且构造函数私有,对外给线程提供各种版本的park()和unpark()方法实现阻塞线程和解除线程阻塞。...

Freertos学习:08-信号量

--- title: rtos-freertos-08-ipc-semaphore date: 2020-06-23 11:01:12 categories: tags: - freertos - ipc --- 章节概述: 介绍 FreeRTOS中的任务间通讯机制:信号量的使用(尽管FreeRTOS中没有进程的概念,但为了统一,我们还是以进程间通讯(IP...

QBC查询

-----------------siwuxie095 QBC 查询 1、QBC,即 Query By Criteria,它是 Hibernate 提供 的另一种查询方式 2、使用 HQL 查询需要写 hql 语句,但使用 QBC 查询 不需要写语句,直接使用方法实现 3、QBC操作的是实体类和属性 4、使用 Criteria对象实现 QBC 查询 基本查...

Lua function 函数

Lua支持面向对象,操作符为冒号‘:’。o:foo(x) <==> o.foo(o, x). Lua程序可以调用C语言或者Lua实现的函数。Lua基础库中的所有函数都是用C实现的。但这些细节对于lua程序员是透明的。调用一个用C实现的函数,和调用一个用Lua实现的函数,二者没有任何区别。 函数的参数跟局部变量一样,用传入的实参来初始化,多余的实...

C#综合揭秘——细说多线程(上)

引言   本文主要从线程的基础用法,CLR线程池当中工作者线程与I/O线程的开发,并行操作PLINQ等多个方面介绍多线程的开发。   其中委托的BeginInvoke方法以及回调函数最为常用。   而 I/O线程可能容易遭到大家的忽略,其实在开发多线程系统,更应该多留意I/O线程的操作。特别是在ASP.NET开发当中,可能更多人只会留意在客户端使用Ajax...

jQuery同步Ajax带来的UI线程阻塞问题及解决办法

俗话说不作死就不会死,今天作死了一回,写了一个比较二逼的函数,遇到了同步Ajax引起的UI线程阻塞问题,在此记录一下。   事情起因是这样的,因为页面上有多个相似的异步请求动作,本着提高代码可重用性的原则,我封装了一个名为getData的函数,它接收不同参数,只负责获取数据,然后把数据return。基本的逻辑剥离出来是这样的: function get...