private CloudAssemblyArtifactResolver(MonoBehaviour coroutineHost, IWWWRequest wwwRequest, string infraServiceUrl, string projectName, string assemblyName, Action <Dictionary <string, string> > onAssetsResolved, Action <Exception> onFailed)
        {
            this.coroutineHost    = coroutineHost;
            this.wwwRequest       = wwwRequest;
            this.infraServiceUrl  = infraServiceUrl;
            this.projectName      = projectName;
            this.assemblyName     = assemblyName;
            this.onAssetsResolved = onAssetsResolved;
            this.onFailed         = onFailed;

            taskRunner = new TaskRunnerWithExponentialBackoff <WWWResponse>();

            state = State.WaitingToStart;
        }
        /// <inheritdoc />
        public void LoadAsset(string prefabName, Action <AssetBundle> onAssetLoaded, Action <Exception> onError)
        {
            var    taskRunner = new TaskRunnerWithExponentialBackoff <Exception>();
            Action runTask    = () => { assetLoader.LoadAsset(prefabName, onAssetLoaded, taskRunner.ProcessResult); };
            Func <Exception, TaskResult> evaluationFunc = (Exception e) =>
            {
                return(new TaskResult
                {
                    IsSuccess = false, // This function should never be called if the load request was successful.
                    ErrorMessage = e.Message
                });
            };
            Action <Exception> onSuccess = (Exception e) => { throw new InvalidOperationException("ExponentialBackoffRetryAssetLoader: TaskRunnerWithExponentialBackoff::onSuccess was called. This code is not supposed to be reachable."); };
            Action <string>    onFailure = (string errorMessage) => { onError(new Exception(errorMessage)); };

            taskRunner.RunTaskWithRetries("ExponentialBackoffRetryAssetLoader::LoadAsset", this, runTask, evaluationFunc, onSuccess, onFailure, MaxRetries, StartBackoffTimeoutMilliseconds / 1000f);
        }