private static async Task ExecuteProcessAsync( ConcurrentDictionary <string, NetworkProcessCallbackContainer> queue, NetworkProcessCallbackContainer container, CancellationTokenSource cancellationSource) { if (cancellationSource.IsCancellationRequested) { queue.AddOrUpdate(container.NetworkProcess.QueueId, container, (key, existingVal) => container); return; } var process = container.NetworkProcess; var callback = container.Callback; var errorCallback = container.ErrorCallback; if (DateTime.Now.Subtract(process.RetryInterval) <= process.LastRetry) { queue.AddOrUpdate(container.NetworkProcess.QueueId, container, (key, existingVal) => container); return; } try { process.LastRetry = DateTime.Now; var processResponse = await process.ProcessRequestAsync(callback.CallbackType); ExecuteCallback(callback, processResponse); } catch (Exception ex) { process.RetryCount++; if (process.CanRetry) { queue.AddOrUpdate(container.NetworkProcess.QueueId, container, (key, existingVal) => container); } else { ExecuteCallback(callback, Activator.CreateInstance(callback.CallbackType)); ExecuteCallback(errorCallback, ex); } } }
/// <summary> /// Adds a network process to the specified priority queue. /// </summary> /// <typeparam name="TProcess"> /// The network process type. /// </typeparam> /// <typeparam name="TResponse"> /// The expected response type. /// </typeparam> /// <typeparam name="TErrorResponse"> /// The expected errored response type. /// </typeparam> /// <param name="process"> /// The network process to execute. /// </param> /// <param name="callback"> /// The action to execute when a response is required. /// </param> /// <param name="errorCallback"> /// The action to execute if the response errors. /// </param> /// <param name="priority"> /// The priority of the process /// </param> public void AddProcess <TProcess, TResponse, TErrorResponse>( TProcess process, Action <TResponse> callback, Action <TErrorResponse> errorCallback, NetworkProcessPriority priority) where TProcess : NetworkProcess { var weakCallback = new WeakCallback(); weakCallback.SetCallback <TResponse>(callback); var weakErrorCallback = new WeakCallback(); weakErrorCallback.SetCallback <TErrorResponse>(errorCallback); var callbackContainer = new NetworkProcessCallbackContainer(process, weakCallback, weakErrorCallback); var queue = this.GetQueueByPriority(priority); queue.AddOrUpdate( callbackContainer.NetworkProcess.QueueId, callbackContainer, (key, val) => callbackContainer); }