/// <summary>
 /// Adds a network process to the specified priority queue.
 /// </summary>
 /// <typeparam name="TResponse">
 /// The expected response type.
 /// </typeparam>
 /// <typeparam name="TProcess">
 /// The network process type.
 /// </typeparam>
 /// <param name="callback">
 /// The action to execute when a response is acquired.
 /// </param>
 /// <param name="priority">
 /// The priority of the process.
 /// </param>
 /// <param name="process">
 /// The network process to execute.
 /// </param>
 public void AddProcess <TResponse, TProcess>(
     Action <TResponse> callback,
     NetworkProcessPriority priority,
     TProcess process) where TProcess : NetworkProcess
 {
     this.AddProcess <TProcess, TResponse, Exception>(process, callback, null, priority);
 }
        private ConcurrentDictionary <string, NetworkProcessCallbackContainer> GetQueueByPriority(
            NetworkProcessPriority priority)
        {
            if (!this.networkQueues.ContainsKey(priority))
            {
                this.networkQueues.Add(priority, new ConcurrentDictionary <string, NetworkProcessCallbackContainer>());
            }

            return(this.networkQueues[priority]);
        }
        /// <summary>
        /// Processes the <see cref="NetworkManager"/> queue by the specified priority.
        /// </summary>
        /// <param name="priority">
        /// The priority of the queue to process.
        /// </param>
        public void ProcessQueueByPriority(NetworkProcessPriority priority)
        {
            var cancellationSource = new CancellationTokenSource();
            var queue = this.GetQueueByPriority(priority);

            var queueTasks = new List <Task>();
            var containers = new List <NetworkProcessCallbackContainer>();

            while (queue.Count > 0)
            {
                NetworkProcessCallbackContainer container;
                if (queue.TryRemove(queue.FirstOrDefault().Key, out container))
                {
                    containers.Add(container);
                }
            }

            foreach (var container in containers)
            {
                queueTasks.Add(ExecuteProcessAsync(queue, container, cancellationSource));
            }
        }
        /// <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);
        }