一起谈.NET技术,C#基础之委托异步

简介:   大家知道委托就相当于C++里面的函数指针,相信大家都很很了解,看看如下简单代码来回想一下委托public delegate void Ad(); xu xus = new xu(); Ad b = new Ad(xus.

  大家知道委托就相当于C++里面的函数指针,相信大家都很很了解,看看如下简单代码来回想一下委托

 
 
public delegate void Ad();
xu xus
= new xu();
Ad b
= new Ad(xus.Add);
b
+= xus.ex;
b();
Console.ReadLine();
 
 
class xu
{
public void Add()
{
// Thread.Sleep(5000);
Console.WriteLine( " sssssssssssssssssssss " );
}
public void ex()
{
// Thread.Sleep(5000);
Console.WriteLine( " aaaaaaaaaaaaaaaaaaaaa " );
}
}

  这里我们看见 定义了一个ADD 的委托没有参数没有返回值 然后把委托指向ADD 和ex 两个方法(多播委托) 然后执行b()  执行之后 结果大家应该知道 就是执行了这2个方法打印出 "ssssssssssssss"于"aaaaaaaaaaaaaaaa"。那如果变成下面这个形式呢?

 
 
public delegate int Ad( int x, int y);
static void Main( string [] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
a
+= ( int x, int y) => { return x - y; };
Console.WriteLine(a(
3 , 2 ));
Console.ReadLine();
}
static int Add( int x, int y)
{
// Thread.Sleep(2000);
return x + y;
}
static int ex( int x, int y)
{
// Thread.Sleep(5000);
return x - y;
}
}

  这段代码 也是执行一个多播委托 但是输出的结果会是什么样的呢 答案是 输出1,为什么前面那个委托会输出2个方法 而这个委托只会输出第二个方法的返回值?如果我们也想输出2个返回值怎么办呢?其实很简单 代码如下

 
 
public delegate int Ad( int x, int y);
static void Main( string [] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
a
+= ( int x, int y) => { return x - y; };
Delegate[] d
= a.GetInvocationList();
for ( int i = 0 ; i < d.Length; i ++ )
{
if (d[i] is Ad)
{
Ad s
= (Ad)d[i];
Console.WriteLine(s(
3 , 2 ));
}
}
Console.ReadLine();
}
static int Add( int x, int y)
{
// Thread.Sleep(2000);
return x + y;
}
static int ex( int x, int y)
{
// Thread.Sleep(5000);
return x - y;
}
}

  这里我们使用了一个GetInvocationList 方法来返回多播委托的调用列表 然后转化ad 然后循环调用 最后显示的结果就是5,1。委托的 复习我们就看到这里 现在回到正题 看看委托的异步调用。

 
 
public delegate int Ad( int x, int y);
static void Main( string [] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3 , 3 ));
Console.WriteLine(
" start " );
Console.ReadLine();
}
static int Add( int x, int y)
{
Thread.Sleep(
2000 );
return x + y;
}

  运行这段代码 会先停顿2秒钟之后再显示6 和start 因为我使用了sleep这个方法 它使该线程休眠2秒钟,所以会在2秒之后显示信息,但是这对用户体验来说是非常糟糕的,那我们怎么改善呢?看看如下代码

 
 
public delegate int Ad( int x, int y);
static void Main( string [] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3 , 3 ));
// Console.WriteLine("start");
IAsyncResult isa = a.BeginInvoke( 3 , 3 , null , null );
while ( ! isa.IsCompleted)
{
Console.WriteLine(
" 未完成 " );
}
int s = a.EndInvoke(isa);
Console.WriteLine(s.ToString());
Console.ReadLine();
}
static int Add( int x, int y)
{
Thread.Sleep(
2000 );
return x + y;
}
static int ex( int x, int y)
{
// Thread.Sleep(5000);
return x - y;
}

  这里我们使用了begininvoke方法来异步执行 委托方法返回一个IAsyncResult 类型的值 代表委托执行的状态,使用一个while循环 来判断IsCompleted 如果没有完成异步调用则不断显示“未完成” 如果完成endinvoke 则返回结果。但是这里需要不断的询问操作完成状态 那么我们怎样让委托异步调用完成之后主动通知我们呢? 看看如下代码

 
 
public delegate int Ad( int x, int y);
static void Main( string [] args)
{
xu xus
= new xu();
Ad a
= new Ad(Add);
Console.WriteLine(a(
3 , 3 ));
IAsyncResult isa
= a.BeginInvoke( 3 , 3 , new AsyncCallback(call), " edit by xyl " );
// 执行你想执行的代码 这里我们还是用IsCompleted来代替
while ( ! isa.IsCompleted)
{
Console.WriteLine(
" 未完成 " );
}
Console.ReadLine();
}
static void call(IAsyncResult isa)
{
AsyncResult ar
= (AsyncResult)isa;
Ad a
= (Ad)ar.AsyncDelegate;
Console.WriteLine(
" this is {0},{1} " ,a.EndInvoke(isa),ar.AsyncState);
}

static int Add( int x, int y)
{
Thread.Sleep(
2000 );
return x + y;
}
static int ex( int x, int y)
{
// Thread.Sleep(5000);
return x - y;
}
}

  这里我们使用了一个call方法 注意它是没有返回值的。把IAsyncResult转换成AsyncResult注意少了个I然后转换成AD 类型的委托 最后endinvoke 来返回值 这样在委托异步执行完成之后会自动通知方法。呵呵 好了今天就说到这里吧。如果有说的不对的地方欢迎指正 大家一起学习一起进步。

目录
相关文章
|
15天前
|
数据可视化 网络协议 C#
C#/.NET/.NET Core优秀项目和框架2024年3月简报
公众号每月定期推广和分享的C#/.NET/.NET Core优秀项目和框架(每周至少会推荐两个优秀的项目和框架当然节假日除外),公众号推文中有项目和框架的介绍、功能特点、使用方式以及部分功能截图等(打不开或者打开GitHub很慢的同学可以优先查看公众号推文,文末一定会附带项目和框架源码地址)。注意:排名不分先后,都是十分优秀的开源项目和框架,每周定期更新分享(欢迎关注公众号:追逐时光者,第一时间获取每周精选分享资讯🔔)。
|
1月前
|
SQL 数据库 C#
C# .NET面试系列十一:数据库SQL查询(附建表语句)
#### 第1题 用一条 SQL 语句 查询出每门课都大于80 分的学生姓名 建表语句: ```sql create table tableA ( name varchar(10), kecheng varchar(10), fenshu int(11) ) DEFAULT CHARSET = 'utf8'; ``` 插入数据 ```sql insert into tableA values ('张三', '语文', 81); insert into tableA values ('张三', '数学', 75); insert into tableA values ('李四',
65 2
C# .NET面试系列十一:数据库SQL查询(附建表语句)
|
1月前
|
开发框架 算法 搜索推荐
C# .NET面试系列九:常见的算法
#### 1. 求质数 ```c# // 判断一个数是否为质数的方法 public static bool IsPrime(int number) { if (number < 2) { return false; } for (int i = 2; i <= Math.Sqrt(number); i++) { if (number % i == 0) { return false; } } return true; } class Progr
58 1
|
1月前
|
并行计算 安全 Java
C# .NET面试系列四:多线程
<h2>多线程 #### 1. 根据线程安全的相关知识,分析以下代码,当调用 test 方法时 i > 10 时是否会引起死锁? 并简要说明理由。 ```c# public void test(int i) { lock(this) { if (i > 10) { i--; test(i); } } } ``` 在给定的代码中,不会发生死锁。死锁通常是由于两个或多个线程互相等待对方释放锁而无法继续执行的情况。在这个代码中,只有一个线程持有锁,且没有其他线程参与,因此不
104 3
|
8天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
12天前
|
数据采集 C# 数据安全/隐私保护
掌握 C# 爬虫技术:使用 HttpClient 获取今日头条内容
本文介绍了如何使用C#的HttpClient与爬虫代理IP技术抓取今日头条内容,以实现高效的数据采集。通过结合亿牛云爬虫代理,可以绕过IP限制,增强匿名性。文中提供了一个代码示例,展示如何设置代理服务器信息、请求头,并用正则表达式提取热点新闻标题。利用多线程技术,能提升爬虫采集效率,为市场分析等应用提供支持。
掌握 C# 爬虫技术:使用 HttpClient 获取今日头条内容
|
1月前
|
开发框架 人工智能 .NET
C#/.NET/.NET Core拾遗补漏合集(持续更新)
C#/.NET/.NET Core拾遗补漏合集(持续更新)
|
1月前
|
SQL 存储 关系型数据库
C# .NET面试系列十:数据库概念知识
#### 1. 为什么要一定要设置主键? 设置主键是数据库设计中的一个重要概念,有几个主要原因: 1、唯一性 ```c# 主键必须保证表中的每一行都有唯一的标识。这样可以避免数据冗余和不一致性。如果没有主键或者主键不唯一,就可能出现数据混乱或错误。 ``` 2、查询性能 ```c# 数据库系统通常会使用主键来加速数据检索。主键通常会被索引,这样可以更快速地找到特定行的数据,提高查询效率。 ``` 3、关联性 ```c# 主键常常用于建立表与表之间的关系。在关系数据库中,一个表的主键通常与其他表中的外键建立关联,这种关系对于数据的一致性和完整性非常重要。 ``` 4、数据完
131 1
C# .NET面试系列十:数据库概念知识
|
1月前
|
XML 开发框架 .NET
C# .NET面试系列八:ADO.NET、XML、HTTP、AJAX、WebService
## 第二部分:ADO.NET、XML、HTTP、AJAX、WebService #### 1. .NET 和 C# 有什么区别? .NET(通用语言运行时): ```c# 定义:.NET 是一个软件开发框架,提供了一个通用的运行时环境,用于在不同的编程语言中执行代码。 作用:它为多语言支持提供了一个统一的平台,允许不同的语言共享类库和其他资源。.NET 包括 Common Language Runtime (CLR)、基础类库(BCL)和其他工具。 ``` C#(C Sharp): ```c# 定义: C# 是一种由微软设计的面向对象的编程语言,专门为.NET 平台开发而创建。 作
174 2
|
1月前
|
开发框架 中间件 .NET
C# .NET面试系列七:ASP.NET Core
## 第一部分:ASP.NET Core #### 1. 如何在 controller 中注入 service? 在.NET中,在ASP.NET Core应用程序中的Controller中注入服务通常使用<u>依赖注入(Dependency Injection)</u>来实现。以下是一些步骤,说明如何在Controller中注入服务: 1、创建服务 首先,确保你已经在应用程序中注册了服务。这通常在Startup.cs文件的ConfigureServices方法中完成。例如: ```c# services.AddScoped<IMyService, MyService>(); //
61 0