分享一个异步任务在遇到IO异常时支持递归回调的辅助方法

public void TryAsyncActionRecursively<TAsyncResult>(
    string asyncActionName,
    Func<Task<TAsyncResult>> asyncAction,
    Action<int> mainAction,
    Action<TAsyncResult> successAction,
    Func<string> getContextInfoFunc,
    Action<Exception> failedAction,
    int retryTimes) where TAsyncResult : AsyncOperationResult
{
    var retryAction = new Action<int>(currentRetryTimes =>
    {
        if (currentRetryTimes >= _immediatelyRetryTimes)
        {
            Task.Factory.StartDelayedTask(_retryIntervalForIOException, () => mainAction(currentRetryTimes + 1));
        }
        else
        {
            mainAction(currentRetryTimes + 1);
        }
    });
    var executeFailedAction = new Action<Exception>(ex =>
    {
        try
        {
            if (failedAction != null)
            {
                failedAction(ex);
            }
        }
        catch (Exception unknownEx)
        {
            _logger.Error(string.Format("Failed to execute the failedCallbackAction of asyncAction:{0}, contextInfo:{1}",
                asyncActionName, getContextInfoFunc()), unknownEx);
        }
    });
    var processTaskException = new Action<Exception, int>((ex, currentRetryTimes) =>
    {
        if (ex is IOException)
        {
            _logger.Error(string.Format("Async task '{0}' has io exception, contextInfo:{1}, current retryTimes:{2}",
                asyncActionName, getContextInfoFunc(), currentRetryTimes), ex);
            retryAction(retryTimes);
        }
        else
        {
            _logger.Error(string.Format("Async task '{0}' has unknown exception, contextInfo:{1}, current retryTimes:{2}",
                asyncActionName, getContextInfoFunc(), currentRetryTimes), ex);
            executeFailedAction(ex);
        }
    });
    var completeAction = new Action<Task<TAsyncResult>>(t =>
    {
        if (t.Exception != null)
        {
            processTaskException(t.Exception.InnerException, retryTimes);
            return;
        }
        if (t.IsCanceled)
        {
            _logger.ErrorFormat("Async task '{0}' was cancelled, contextInfo:{1}, current retryTimes:{2}",
                asyncActionName, getContextInfoFunc(), retryTimes);
            retryAction(retryTimes);
            return;
        }
        var result = t.Result;
        if (result.Status == AsyncOperationResultStatus.IOException)
        {
            _logger.ErrorFormat("Async task '{0}' has io exception, contextInfo:{1}, current retryTimes:{2}, errorMsg:{3}",
                asyncActionName, getContextInfoFunc(), retryTimes, result.ErrorMessage);
            retryAction(retryTimes);
            return;
        }
        if (successAction != null)
        {
            successAction(result);
        }
    });

    try
    {
        asyncAction().ContinueWith(completeAction);
    }
    catch (IOException ex)
    {
        _logger.Error(string.Format("Execute async action '{0}' failed, contextInfo:{1}, current retryTimes:{2}",
            asyncActionName, getContextInfoFunc(), retryTimes), ex);
        retryAction(retryTimes);
    }
    catch (Exception ex)
    {
        _logger.Error(string.Format("Execute async action '{0}' failed, contextInfo:{1}, current retryTimes:{2}",
            asyncActionName, getContextInfoFunc(), retryTimes), ex);
        executeFailedAction(ex);
    }
}

该函数的功能是:执行一个异步任务(返回Task的方法),如果执行出现IO异常,则重试当前主函数(mainAction);用户的mainAction中会再次调用TryAsyncActionRecursively方法。从而实现当遇到IO异常时,能做到不断重试。另外,重试只立即重试指定的次数,超过指定次数,则不立即重试,而是暂停一定间隔后再次执行。该函数还提供当acyncAction执行成功或失败后的回调函数,以及允许传入当前上下文的一些说明信息,以便记录有意义的错误日志信息。

下面是使用示例:

private void PublishEventAsync(ProcessingCommand processingCommand, EventStream eventStream, int retryTimes)
{
    TryAsyncActionRecursively<AsyncOperationResult>("PublishEventAsync",
    () => _eventPublisher.PublishAsync(eventStream),
    currentRetryTimes => PublishEventAsync(processingCommand, eventStream, currentRetryTimes),
    result =>
    {
        _logger.DebugFormat("Publish events success, {0}", eventStream);
        processingCommand.Complete(new CommandResult(CommandStatus.Success, processingCommand.Command.Id));
    },
    () => string.Format("[eventStream:{0}]", eventStream),
    ex => processingCommand.Complete(new CommandResult(CommandStatus.Failed, processingCommand.Command.Id)),
    retryTimes);
}

PublishEventAsync(processingCommand, eventStream, 0);
时间: 2024-11-03 21:06:48

分享一个异步任务在遇到IO异常时支持递归回调的辅助方法的相关文章

小脑袋竞价分析软件分享一个90后站长的推广方式

网站推行宣传一直是咱们小站长比较难的作业,作为小站长的咱们没有雄厚的资金,拉赞助更是简直不可能.特别是我这种村庄的90后学生站长,做网站根柢靠节约日子费. 所以买广告更是不太实习,我去过ALIMAMA买广告位,可是作用都不明显,由于我买不起报价高的位子,只需买那些价廉并且IP高的.可是那些方位80%都是刷的IP,真实IP少作用当然欠好.好了咱们进入主题,昨天我给咱们同享的是在互联网上的免费构思推行方法,今天我说说在咱们实习日子中我是如何宣传网站的,仍是说一下,小脑袋竞价分析软件分享一个90后站长

分享一个很好用的图标库(icomoon.io)

分享一个很好用的图标库(icomoon.io)链接,这个图标库可以将自己所需要的图标打包并下载使用.

V5Shop分享一个独立网店快速提升PR和销售额的方法

V5Shop分享一个独立网店快速提升PR和销售额的方法 很多独立网店的店主都在为宣传推广头疼.在现在这个产品丰富的市场经济环境下,各行各业的竞争都异常激烈,"酒香也怕巷子深"已经成为网商们的共识.作为独立网店,独立运营固然可以避免许多"拼低价"的竞争,客户对网店和品牌的忠诚度也有保证,但是在推广这个问题上,却难住了不少网商. 许多网商之所以过于依赖淘宝等大型平台,就是因为这些平台能够为其带来源源不断的客户,其不用为如何招揽客户,如何推广网店而劳心.有得必有失,这同样

spark读取hdfs的时候出现io异常

问题描述 我现在只部署了一个节点来测试,但是发现无法读取hdfs上的文件,每次都抛出这个io异常.求大神拯救nero01为主机名,192.168.189.101为ip地址.scala>textFile.countjava.io.IOException:Failedonlocalexception:com.google.protobuf.InvalidProtocolBufferException:Messagemissingrequiredfields:callId,status;HostDet

java.sql.SQLException: Io 异常: 连接超时

问题描述 帮我看看咋回事啊?我搞不懂.就是运行很久的一个项目,最近突然就动不动就登陆不了,然后连首页都显示不出来了.然后只能重启服务,就又没问题了.老师需要重启.帮我看看日志全是这个,是什么意思啊?ERROR 2013-12-06 13:12:20,831 org.logicalcobwebs.proxool.GAP-Pool #0041 encountered errors during destruction: java.sql.SQLException: Io 异常: 连接超时at ora

分享一个Android和java调用RESTful Web服务的利器Resting

分享一个Android和java调用RESTful Web服务的利器Resting   当我们调用Web服务,往往是最终目标是取HTTP响应,将其转化为将在应用中呈现的值对象.Resting可以用来实现这一功能.Resting,在Java的一个轻量级的REST框架,可用于调用一个RESTful Web服务,并转换成响应来自客户端应用程序定制的Java对象.由于它的简单,resting是适合Android等手持设备.   resting目标•暴露简单的get(),post(),put()和dele

急 hibernate 循环执行insert时出现 Io 异常: The Network Adapter could not establish the

问题描述 org.springframework.jdbc.UncategorizedSQLException:Hibernateoperation:Cannotopenconnection;uncategorizedSQLExceptionforSQL[???];SQLstate[null];errorcode[17002];Io异常:TheNetworkAdaptercouldnotestablishtheconnection;nestedexceptionisjava.sql.SQLExc

连接数据库报错Io 异常: The Network Adapter could not establish the

问题描述 一个纠结好久的问题,小女对JAVA实在是门外汉,只能求教诸位高人了...起因是负责运营的系统平时连接都很正常,但是到业务高峰期服务器经常发生瞬堵,检查后台日志,报错信息如下:解决方案二:<2011-4-2下午05时30分29秒CST><Info><JDBC><cnsz030356><ICSs-GCCSFServer1146><ExecuteThread:'23'forqueue:'weblogic.kernel.Default'&

写了一个JDBC就出了个异常,哎。。

问题描述 在电脑里装了一个oracle11g想用eclipse写个连接数据的程序,复习一下JDBC,代码如下:packageoracle;importjava.sql.Connection;importjava.sql.DriverManager;importjava.sql.PreparedStatement;importjava.sql.ResultSet;importjava.sql.SQLException;publicclassSQLManager{privatestaticfinal