Share an asynchronous task that supports the secondary method of recursive callback when an IO exception occurs. io Recursion

Source: Internet
Author: User

Share an asynchronous task that supports the secondary method of recursive callback when an IO exception occurs. io Recursion

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}, try to run the async task again.",                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; } var result = t.Result; if (result.Status == AsyncOperationResultStatus.IOException) { _logger.ErrorFormat("Async task '{0}' result status is io exception, contextInfo:{1}, current retryTimes:{2}, errorMsg:{3}, try to run the async task again.", asyncActionName, getContextInfoFunc(), retryTimes, result.ErrorMessage); retryAction(retryTimes); return; } if (successAction != null) { successAction(result); } }); try { asyncAction().ContinueWith(completeAction); } catch (IOException ex) { _logger.Error(string.Format("IOException raised when executing async action '{0}', contextInfo:{1}, current retryTimes:{2}, try to run the async task again.", asyncActionName, getContextInfoFunc(), retryTimes), ex); retryAction(retryTimes); } catch (Exception ex) { _logger.Error(string.Format("Unknown exception raised when executing async action '{0}', contextInfo:{1}, current retryTimes:{2}", asyncActionName, getContextInfoFunc(), retryTimes), ex); executeFailedAction(ex); }}

This function is used to execute an asynchronous Task (return the Task method). If an IO exception occurs during execution, retry the current main function (mainAction ); the user's mainAction will call the TryAsyncActionRecursively method again.

In this way, when an I/O exception occurs, you can try again. In addition, only the specified number of retries is allowed. If the number of retries is exceeded, the Retry is not performed immediately. Instead, the Retry is paused for a certain interval and then executed again.

This function also provides callback functions when acyncAction is executed successfully or fails, as well as some description information about the current context that can be passed in to record meaningful error log information.

The following is an example:

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, null, null, null));    },    () => string.Format("[eventStream:{0}]", eventStream),    ex => processingCommand.Complete(new CommandResult(CommandStatus.Failed, processingCommand.Command.Id, null, null, "Publish events failed.")),    retryTimes);}
PublishEventAsync(processingCommand, eventStream, 0);

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.