Public voidTryasyncactionrecursively<tasyncresult>( stringAsyncactionname, Func<Task<TAsyncResult>>asyncaction, Action<int>mainaction, Action<TAsyncResult>successaction, Func<string>Getcontextinfofunc, Action<Exception>Failedaction,intRetrytimes)wheretasyncresult:asyncoperationresult{varRetryaction =Newaction<int> (Currentretrytimes = { if(Currentretrytimes >_immediatelyretrytimes) {Task.Factory.StartDelayedTask (_retryintervalforioexception, ()= Mainaction (Currentretrytimes +1)); } Else{mainaction (currentretrytimes+1); } }); varExecutefailedaction =NewAction<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); } }); varProcesstaskexception =NewAction<exception,int> (ex, currentretrytimes) = { if(ex isIOException) {_logger. Error (string. Format ("the async task ' {0} ' has IO exception, contextinfo:{1}, current retrytimes:{2}, and 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); } }); varCompleteaction =NewAction<task<tasyncresult>> (t = { if(T.exception! =NULL) {processtaskexception (t.exception.innerexception, retrytimes); return; } varresult =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 TA SK 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); }}
The function performs an asynchronous task (a method that returns a task) and retries the current main function (mainaction) If an IO exception occurs, and the Tryasyncactionrecursively method is called again in the user's mainaction.
This allows for constant retries when encountering IO anomalies. In addition, retries are retried only a specified number of times, more than a specified number of times, and are not retried immediately, but are executed again after a certain interval has been paused.
The function also provides a callback function after the success or failure of the acyncaction, as well as some descriptive information that allows the current context to be passed in to record meaningful error log information.
The following are examples of use:
Private voidPublisheventasync (Processingcommand Processingcommand, EventStream EventStream,intretrytimes) {tryasyncactionrecursively<AsyncOperationResult> ("Publisheventasync", () =_eventpublisher.publishasync (eventstream), Currentretrytimes=Publisheventasync (Processingcommand, EventStream, currentretrytimes), result={_logger. Debugformat ("Publish Events success, {0}", EventStream); Processingcommand.complete (NewCommandresult (commandstatus.success, ProcessingCommand.Command.Id,NULL,NULL,NULL)); }, () =string. Format ("[eventstream:{0}]", EventStream), ex= Processingcommand.complete (NewCommandresult (commandstatus.failed, ProcessingCommand.Command.Id,NULL,NULL,"Publish events failed.") ), retrytimes);}
0);
Share an auxiliary method that supports recursive callbacks when an asynchronous task encounters an IO exception