ABCD四个顺序执行方法,拓展性延申
今天在群里,有人问
有几个void返回值的方法,但是我想让这几个方法有执行顺序,要怎么处理,ABCD 四个方法,依次执行,但是这几个方法都是无返回值的
这个问题其实很简单,如果方法是同步方法,直接四个方法连续写就好了,比如:
static void Main()
{
A();
B();
C();
D();
}
但是如果方法里面包含了耗时操作,那么四个这样写就有问题了,执行顺序就错掉了,我们需要利用callback函数来进行操作,但是本着能不动原方法就不动的理念,我们使用Task的OnCompleted事件(.net framework中可以使用BeginInvoke(callback,null))来做处理
- 如果方法有返回值,则使用Func,或者Func<>
- 如果方法没有返回值,则使用Action,或者Action<>
1. 无返回值在.net core中使用Task的OnCompleted事件
由于是没有返回值的方法,我们使用
例如
static void Main()
{
Action action1 = () => {
Thread.Sleep(1000);
Console.WriteLine("action1");
};
Action action2 = () => {
Thread.Sleep(2000);
Console.WriteLine("action2");
};
Action action3 = () => {
Thread.Sleep(3000);
Console.WriteLine("action3");
};
Action action4 = () => {
Thread.Sleep(3000);
Console.WriteLine("action4");
};
Stack st = new Stack();
st.Push(action2);
st.Push(action3);
st.Push(action4);
void MyAsynCallback()
{
if (st.Count > 0)
{
var action = (Action)st.Pop();
Task.Run(action).GetAwaiter().OnCompleted(() =>
{
MyAsynCallback();
});
}
}
Task.Run(action1).GetAwaiter().OnCompleted(() =>
{
MyAsynCallback();
});
Console.ReadLine();
//Stack的Pop是先进后出,输出顺序action1 action4 action3 action2
}
我们可以将Stack改成其他的,比如List、Queue等,自行判断是否需要手动弹出action即可
2. 无返回值在.net framework中使用BeginInvoke
static void Main()
{
Action action1 = () => {
Thread.Sleep(1000);
Console.WriteLine("action1");
};
Action action2 = () => {
Thread.Sleep(2000);
Console.WriteLine("action2");
};
Action action3 = () => {
Thread.Sleep(3000);
Console.WriteLine("action3");
};
Action action4 = () => {
Thread.Sleep(3000);
Console.WriteLine("action4");
};
Stack st = new Stack();
st.Push(action2);
st.Push(action3);
st.Push(action4);
void MyAsynCallback(IAsyncResult async)
{
if (st.Count > 0)
{
var action = (Action)st.Pop();
action.BeginInvoke(new AsyncCallback(MyAsynCallback),null);
}
}
action1.BeginInvoke(new AsyncCallback(MyAsynCallback), null);
Console.ReadLine();
//Stack的Pop是先进后出,输出顺序action1 action4 action3 action2
}
3. 有返回值在.net core中使用Task的OnCompleted事件
由于是没有返回值的方法,我们使用
例如
static void Main()
{
Func<int> func1 = () => {
Thread.Sleep(1000);
Console.WriteLine("func1");
return 1;
};
Func<int> func2 = () => {
Thread.Sleep(2000);
Console.WriteLine("func2");
return 1;
};
Func<int> func3 = () => {
Thread.Sleep(3000);
Console.WriteLine("func3");
return 0;
};
Func<int> func4 = () => {
Thread.Sleep(3000);
Console.WriteLine("func4");
return 1;
};
Stack st = new Stack();
st.Push(func2);
st.Push(func3);
st.Push(func4);
void MyAsynCallback(int result)
{
if (st.Count > 0 && result > 0)
{
var action = (Func<int>)st.Pop();
var task1 = Task.Run(action);
task1.GetAwaiter().OnCompleted(() =>
{
MyAsynCallback(task1.Result);
});
}
}
var task = Task.Run(func1);
task.GetAwaiter().OnCompleted(() =>
{
MyAsynCallback(task.Result);
});
Console.ReadLine();
//Stack的Pop是先进后出,输出顺序func1 func4 func3 func2
}
4. 有返回值在.net framework中使用BeginInvoke
delegate int dele_func(int a);
static void Main()
{
Func<int> func1 = () => {
Thread.Sleep(1000);
Console.WriteLine("func1");
return 1;
};
Func<int> func2 = () => {
Thread.Sleep(2000);
Console.WriteLine("func2");
return 1;
};
Func<int> func3 = () => {
Thread.Sleep(3000);
Console.WriteLine("func3");
return 1;
};
Func<int> func4 = () => {
Thread.Sleep(3000);
Console.WriteLine("func4");
return 1;
};
Stack st = new Stack();
st.Push(func2);
st.Push(func3);
st.Push(func4);
void MyAsynCallback(IAsyncResult async)
{
dele_func dele_Func2 = (dele_func)async.AsyncState;
int result = dele_Func2.EndInvoke(async);
if (st.Count > 0 && result > 0)
{
var action = (Func<int>)st.Pop();
dele_func dele_Func1 = new dele_func((int a) => { return action.Invoke(); });
IAsyncResult asyncResult1 = dele_Func1.BeginInvoke(0, new AsyncCallback(MyAsynCallback), dele_Func1);
}
}
dele_func dele_Func = new dele_func((int a) => { return func1.Invoke(); });
IAsyncResult asyncResult = dele_Func.BeginInvoke(0, new AsyncCallback(MyAsynCallback), dele_Func);
Console.ReadLine();
//Stack的Pop是先进后出,输出顺序func1 func4 func3 func2
}
有返回值时,可以根据result的判断,来判断是否继续往下执行
如有问题,欢迎指正
ABCD四个顺序执行方法,拓展性延申的更多相关文章
- c#线程顺序执行
using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...
- Node.js的那些坑——如何让异步并发方法同步顺序执行(for循环+异步操作)
1 前言 nodejs的回调,有时候真的是让人又爱又恨的,当需要用for循环把数据依次存入数据库,但是如果使用正常的for循环,永远都是最后一次值的记录,根本不符合要求. 解决此方案有几种,例如闭包( ...
- 三个线程T1,T2,T3.保证顺序执行的三种方法
经常看见面试题:有三个线程T1,T2,T3,有什么方法可以确保它们按顺序执行.今天手写测试了一下,下面贴出目前想到的3种实现方式 说明:这里在线程中我都用到了sleep方法,目的是更容易发现问题.之前 ...
- ajax异步导致js方法顺序执行不了
js两个方法调用的顺序,有时候是这样的 f1(); f2(); 本来是先执行f1的,但是如果f1里面进行ajax异步 async:true,那么可能会先执行f2,如果想要顺序执行,那么就把异步设 ...
- c#数据四种执行方法(ExecuteNonQuery)-----转载
c#数据四种执行方法(ExecuteNonQuery) 1.使用ExecuteReader()操作数据库 2.使用ExecuteNonQuery()操作数据库 3.使用ExecuteScalar( ...
- 使用定时器判断确保某个标签有值才执行方法, 控制js代码执行先后顺序
使用定时器判断确保某个标签有值才执行方法: var wait = setInterval(function(){ var diqu = $("#diqu").val(); //确保 ...
- 更优雅的方式: JavaScript 中顺序执行异步函数
火于异步 1995年,当时最流行的浏览器--网景中开始运行 JavaScript (最初称为 LiveScript). 1996年,微软发布了 JScript 兼容 JavaScript.随着网景.微 ...
- {Django基础九之中间件} 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证
Django基础九之中间件 本节目录 一 前戏 二 中间件介绍 三 自定义中间件 四 中间件的执行流程 五 中间件版登陆认证 六 xxx 七 xxx 八 xxx 一 前戏 我们在前面的课程中已经学会了 ...
- js的并行加载以及顺序执行
重新温习了下这段内容,发现各个浏览器的兼容性真的是搞大了头,处理起来很是麻烦. 现在现总结下并行加载多个js的方法: 1,对于动态createElement('script')的方式,对所有浏览器都是 ...
随机推荐
- Star Way To Heaven
题目描述 小 x伤心的走上了 Star way to heaven. 到天堂的道路是一个笛卡尔坐标系上一个 n*m的长方形通道 顶点在0,0 和 . 小 n,m 从最左边任意一点进入,从右边任意一点走 ...
- windows 找不到文件gpedit.msc
前言: 最新在装一个软件的时候,需要更改本地组的一些内容,win+R输入gpedit.msc,提示找不到文件. 解决: 第一种方法:笔者电脑是window10 家庭版,试了网上新建一个txt文件,写入 ...
- [Docker] 在CentOS6.8 安装 Docker
运行docker Linux内核版本需要在3.8以上,针对centos6.5 内核为2.6的系统需要先升级内核.不然会特别卡,退出容器. # 查看当前版本: cat /etc/issue # 导入pu ...
- test_1 计算字符串最后一个单词的长度,单词以空格隔开
题目描述:计算字符串最后一个单词的长度,单词以空格隔开. 输入描述: 一行字符串,非空,长度小于5000. 输出描述: 整数N,最后一个单词的长度. #coding=utf-8 str = raw_ ...
- ArcGIS把导入的shp按渔网区块分割成更小的文件
前言 前端地图的开发需要导入城市的3D建筑白模,如果直接导入整个城市的json,文件大小高达76M,浏览器会直接崩溃,所以需要用ArcGIS分割成更小的文件后再给前端导入展示. ArcGIS版本:10 ...
- 热词cloud-EChart安装
1.安装npm install echarts npm install echarts-wordcloud注意版本:echarts版本5只能和wordcloud版本2的一起使用 :echarts版本4 ...
- CMake语法—普通变量与子目录(Normal Variable And Subdirectory)
目录 CMake语法-普通变量与子目录(Normal Variable And Subdirectory) 1 CMake普通变量与子目录示例 1.1 代码目录结构 1.2 父目录CMakeLists ...
- Go 函数,包(二)
#### Go 函数,包(二)***百丈峰,松如浪,地势坤,厚德载物之像*** 今天又到周五啦,你们有没有激动呢,反正我很激动,又有两天的自由了; 上一节我们学习了Go 的函数和包的一些知识 , 今天 ...
- java单例模式(饿汉式和懒汉式)
1 /* 2 * 设计模式:对问题行之有效的解决方式.其实它是一种思想. 3 * 4 * 1,单例设计模式 5 * 解决的问题:就是可以保证一个类在内容中的对象唯一性. 6 * 7 * 必须对于多个程 ...
- 腾讯云轻量服务器通过Docker搭建外网可访问连接的redis5.x集群
总结记录/朱季谦 最近买了一台4核16的腾讯云轻量应用服务器,花了我快四百的大洋,打算搭建一堆docker组件集群,最先开始是通过docker搭建redis集群,计划使用三个端口,分别是7001,70 ...