关于异步任务串行执行的思考与实现

最近在做的一个需求被产品的各种奇葩要求和各种为了体验的迷之借口搞得面目前非,里面有很多异步请求,而且有时候是独立执行,有时候需要相互依赖的串行执行(A的结果回来了,成功的话执行B,不成功不管)。一开始我都是非常简单的在Activity中实现各种回调接口,然后在回调方法中调用下一个异步请求,为了能串行的执行,因此加了很多boolean值标记当前什么状态。然后我就想做一个可以封装异步任务,然后按照顺序异步执行的一个模式。

我希望使用的时候,可以new一个AsyncTask对象,然后它成功的后执行什么,失败的后执行什么这样封装好。用起来大概是这个样子:

1 TaskA taskA = new TaskA();
2 TaskB taskB = new TaskB();
3 TaskC taskC = new TaskC();
4 taskA.success(tastB).failure(taskC);

于是我就写了一个这样的东西:

public abstract class AsyncTask {

    private static final int EXEC_TYPE_TASK = 1;
    private static final int EXEC_TYPE_RUNNABLE = 2;

    private int mAfterSuccessExecWhat = EXEC_TYPE_TASK;
    private int mAfterFailureExecWhat = EXEC_TYPE_TASK;

    private AsyncTask mAfterSuccessTask = null;
    private AsyncTask mAfterFailureTask = null;
    private Runnable mAfterSuccessRunnable = null;
    private Runnable mAfterFailureRunnable = null;

    public final void start() {
        onBegin();
        onWork();
    }

    protected void onBegin() {

    }

    protected abstract void onWork();

    protected void onEndSuccess(Object ... object) {
        switch (mAfterSuccessExecWhat) {
            case EXEC_TYPE_TASK:
                if (mAfterSuccessTask != null) {
                    mAfterSuccessTask.start();
                }
                break;
            case EXEC_TYPE_RUNNABLE:
                if (mAfterSuccessRunnable != null) {
                    mAfterSuccessRunnable.run();
                }
                break;
        }

    }

    protected void onEndFailure(Object ... object) {
        switch (mAfterFailureExecWhat) {
            case EXEC_TYPE_TASK:
                if (mAfterFailureTask != null) {
                    mAfterFailureTask.start();
                }
                break;
            case EXEC_TYPE_RUNNABLE:
                if (mAfterFailureRunnable != null) {
                    mAfterFailureRunnable.run();
                }
                break;
        }

    }

    public final AsyncTask afterSuccessExec(AsyncTask nextTask) {
        mAfterSuccessTask = nextTask;
        mAfterSuccessExecWhat = EXEC_TYPE_TASK;
        return this;
    }

    public final AsyncTask afterFailureExec(AsyncTask nextTask) {
        mAfterFailureTask = nextTask;
        mAfterFailureExecWhat = EXEC_TYPE_TASK;
        return this;
    }

    public final AsyncTask afterSuccessRun(Runnable runnable) {
        mAfterSuccessRunnable = runnable;
        mAfterSuccessExecWhat = EXEC_TYPE_RUNNABLE;
        return this;
    }

    public final AsyncTask afterFailureRun(Runnable runnable) {
        mAfterFailureRunnable = runnable;
        mAfterFailureExecWhat = EXEC_TYPE_RUNNABLE;
        return this;
    }
}

然后,假设有两个任务,一个是检测异常,就是传一些参数,然后发起一个网络请求,让后台的逻辑来判断是否异常并且返回。另一个是发起一个创建请求。这些属于业务逻辑部分,就简单的写下。

public class YourEngine {

    interface OnExceptionResultCallback {
        void onResult(int errorCode);

    }

    interface OnCreateAttendanceResultCallback {
        void onResult(int errorCode);
    }

    public static void requestException(int data, OnExceptionResultCallback callback) {
        System.out.println("开始检测异常");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("网络回调过来");

        if (data == 100) {
            if (callback != null) {
                callback.onResult(0);
            }
        } else {
            if (callback != null) {
                callback.onResult(1);
            }
        }

    }

    public static void requestCreateAttendance(int data, OnCreateAttendanceResultCallback callback) {

        System.out.println("开始创建考勤");
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("网络回调过来");

        if (data == 100) {
            if (callback != null) {
                callback.onResult(0);
            }
        } else {
            if (callback != null) {
                callback.onResult(1);
            }
        }
    }
}

然后,接下来有两种场景,第一种是检测异常的请求可以单独发送。另一种是先发送检测异常的请求,如果返回成功,那么再发送创建考勤的请求,否则的话则什么都不干。

如果按原始的方式来搞,我需要在第一个回调中做判断是否需要进行下一个异步任务。这样就比较恶心了,一堆布尔值很烦。

所以,搞出了上面这个AsyncTask之后,工作就简单了。用起来的时候,就像这样:

CheckExceptionTask checkExceptionTask = new CheckExceptionTask();
CreateAttendanceTask createTask = new CreateAttendanceTask();

checkExceptionTask.afterSuccessExec(createTask).afterFailureExec(null);
checkExceptionTask.start();

这样就是基本的一个实现,用起来就爽了。

时间: 2024-11-03 22:01:30

关于异步任务串行执行的思考与实现的相关文章

【iOS面试系列-2】多线程中同步、异步和串行、并行之间的逻辑关系(必考,必须掌握)

一.同步.异步和串行.并行 任务串行执行就是每次只有一个任务被执行,任务并发执行就是在同一时间可以有多个任务被执行. 一个同步函数只在完成了它预定的任务后才返回.一个异步函数,刚好相反,会立即返回,预定的任务会完成但不会等它完成.因此,一个异步函数不会阻塞当前线程去执行下一个函数. (来源:http://www.cocoachina.com/industry/20140428/8248.html) 队列分为串行和并行 任务的执行分为同步和异步 -------  队列只是负责任务的调度,而不负责任

loadrunner多场景的串行执行以及定时执行

方法一: 既然是脚本串行执行,那在场景设计中必然是要用多个脚本,要注意的是需要将Scenario Schedule中的Schedule by设置为Group的模式.然后按实际需要依次设置每个脚本的Schedule.要事先计算好每个脚本的整个执行时间,方便定义后续脚本的开始时间(设置Start Group). 方法二: 使用定时任务执行: 首先创建并设置好要跑的个测试场景,再创建一个一个批处理程序按先后顺序调用这几个个场景进行测试,最后通过Windows的定时任务设定批处理的执行时间 写一个批处理

异步任务+并行队列情况与异步任务+串行队列(主队列)情况

异步任务+并行队列 把异步任务放到并行队列进行执行,异步任务会在不同的线程中执行. /*异步执行+并行队列*/ - (IBAction)clickBasic1:(UIButton *)sender { //全局并行队列 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); //异步执行 dispatch_async(queue, ^{ for (int i = 0; i<2;

oracle中并行执行不一定比串行执行快

并行执行与串行执行相比,能否缩短执行时间,取决于如下几个方面:1.待执行的目标SQL是否适合并行执行,有些SQL是不太适合并行执行的,比如走索引的嵌套循环连接.2.数据库服务器上的硬件资源(如CPU.内存.I/O等)是否还有富余.3.并行执行时,是否最大化地利用了数据库服务器上的硬件资源(但同时又不能使数据库服务器上的硬件资源消耗殆尽).4.待执行的目标SQL的并行执行计划是否为当前情形下的最优执行计划. 原文地址:https://www.cnblogs.com/qinjf/p/8414654.

spring定时器任务多任务串行执行问题排查

原文:https://www.cnblogs.com/youtianhong/p/6027249.html 最近发现个生产问题,定时器任务某些任务没有及时执行.经过研究排查发现spring 定时器任务scheduled-tasks默认配置是单线程串行执行的,这就造成了若某个任务执行时间过长,其他任务一直在排队,业务逻辑没有及时处理的问题. 如下是scheduled定义了3个任务. <task:scheduled-tasks > <task:scheduled ref="myTa

背水一战 Windows 10 (118) - 后台任务: 后台下载任务(任务分组,并行或串行执行,组完成后通知)

[源码下载] 作者:webabcd 介绍背水一战 Windows 10 之 后台任务 后台下载任务(任务分组,并行或串行执行,组完成后通知) 示例演示后台下载任务的分组,以及如何设置组内任务是并行执行还是串行执行,以及组任务全部完成后如何 toast 或 tile 通知)BackgroundTask/TransferModel.cs /* * 扩展了 DownloadOperation 和 UploadOperation,用于 MVVM 绑定数据 */ using System; using S

ios--进程/多线程/同步任务/异步任务/串行队列/并行队列(对比分析)

现在先说两个基本的概念,啥是进程,啥是线程,啥又是多线程;先把这两个总是给弄清再讲下面的 进程:正在进行的程序,我们就叫它进程. 线程:线程就是进程中的一个独立的执行路径.这句话怎么理解呢! 一个程序它是按顺序从上往下执行的, 这个执行顺序我们可以把它看成是一条线,把这条线就叫做线程(个人理解,错了勿喷);每一个程序中至少包含一条线程, 这条线程,我们叫它主线程. 多线程:多线程也就是说一个程序中有多条执行路径.在iOS当中将一些比较耗时的操作放到另一条执行路径里.让它与主线程同时运行.这样不会

iOS-线程之GCD方式---之同步异步和串行队列并行队列之间的关系

GCD方式是Apple官方推荐实现多线程的方式 但在这之前必须理清楚同步,异步,串行队列,并行队列之间的概念. 同步:即当前的执行程序块不会创建一个新的线程,只能在当前线程中执行. 异步:会在当前的线程之外创建一个新的线程,并在新的线程中执行代码块. 首先声明一点,队列是用来存放即将执行的线程体的. 串行队列:串行队列中的线程满足FIFO(First In First Out),并且只有在先出的线程执行完,后续的线程才能出队列执行.(很可能造成APP的假死状态) 并行队列:并行队列也满足FIFO

iOS GCD, 同步,异步,串行队列,并行队列,dispatch_group

同步,指代码在同一个线程运行 异步,代码在另一个线程运行 串行队列,提交到该队列的block会顺序执行 并行队列,提交到该队列的block会并发执行 如果想等某一队列中所有block都执行完了在执行一个操作,在串行队列中,可以把最后需要执行的block放在队列最后即可,但是在并行队列中,可以用dispatch_group,最后通过dispatch_group_notify来执行最后要执行的block. 待编辑,补充例子.