/// <summary>
            /// Prepares the specified resource for access by a lock holder.
            /// </summary>
            /// <param name="resource">The resource to prepare.</param>
            /// <param name="cancellationToken">The token whose cancellation signals lost interest in this resource.</param>
            /// <param name="forcePrepareConcurrent">Force preparation of the resource for concurrent access, even if an exclusive lock is currently held.</param>
            /// <returns>A task that is completed when preparation has completed.</returns>
            private Task PrepareResourceAsync(TResource resource, CancellationToken cancellationToken, bool forcePrepareConcurrent = false)
            {
                Requires.NotNull(resource, nameof(resource));
                Assumes.True(Monitor.IsEntered(this.service.SyncObject));

                // We deliberately ignore the cancellation token in the tasks we create and save because the tasks can be shared
                // across requests and we can't have task continuation chains where tasks within the chain get canceled
                // as that can cause premature starting of the next task in the chain.
                bool   forConcurrentUse = forcePrepareConcurrent || !this.service.IsWriteLockHeld;
                var    finalState       = forConcurrentUse ? ResourceState.Concurrent : ResourceState.Exclusive;
                object stateObject      = forConcurrentUse
                    ? (object)resource
                    : Tuple.Create(resource, this.service.GetAggregateLockFlags());

                if (!this.resourcePreparationTasks.TryGetValue(resource, out ResourcePreparationTaskAndValidity preparationTask))
                {
                    var preparationDelegate = forConcurrentUse
                        ? this.prepareResourceConcurrentDelegate
                        : this.prepareResourceExclusiveDelegate;

                    // We kick this off on a new task because we're currently holding a private lock
                    // and don't want to execute arbitrary code.
                    // Let's also hide the ARWL from the delegate if this is a shared lock request.
                    using (forConcurrentUse ? this.service.HideLocks() : default(Suppression))
                    {
                        preparationTask = new ResourcePreparationTaskAndValidity(
                            Task.Factory.StartNew(preparationDelegate, stateObject, CancellationToken.None, TaskCreationOptions.None, TaskScheduler.Default).Unwrap(),
                            finalState);
                    }
                }
                else if (preparationTask.State != finalState || preparationTask.PreparationTask.IsFaulted)
                {
                    var preparationDelegate = forConcurrentUse
                        ? this.prepareResourceConcurrentContinuationDelegate
                        : this.prepareResourceExclusiveContinuationDelegate;

                    // We kick this off on a new task because we're currently holding a private lock
                    // and don't want to execute arbitrary code.
                    // Let's also hide the ARWL from the delegate if this is a shared lock request.
                    using (forConcurrentUse ? this.service.HideLocks() : default(Suppression))
                    {
                        preparationTask = new ResourcePreparationTaskAndValidity(
                            preparationTask.PreparationTask.ContinueWith(preparationDelegate, stateObject, CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.Default).Unwrap(),
                            finalState);
                    }
                }

                Assumes.NotNull(preparationTask.PreparationTask);
                this.resourcePreparationTasks[resource] = preparationTask;

                // We tack cancellation onto the task that we actually return to the caller.
                // This doesn't cancel resource preparation, but it does allow the caller to return early
                // in the event of their own cancellation token being canceled.
                return(preparationTask.PreparationTask.WithCancellation(cancellationToken));
            }
예제 #2
0
            /// <summary>
            /// Sets the specified resource to be considered in an unknown state. Any subsequent access (exclusive or concurrent) will prepare the resource.
            /// </summary>
            private void SetUnknownResourceState(TResource resource)
            {
                Requires.NotNull(resource, nameof(resource));

                lock (this.service.SyncObject)
                {
                    this.resourcePreparationTasks.TryGetValue(resource, out ResourcePreparationTaskAndValidity previousState);
                    this.resourcePreparationTasks[resource] = new ResourcePreparationTaskAndValidity(
                        previousState.PreparationTask ?? Task.CompletedTask, // preserve the original task if it exists in case it's not finished
                        ResourceState.Unknown);
                }
            }
            /// <summary>
            /// Sets the specified resource to be considered in an unknown state. Any subsequent access (exclusive or concurrent) will prepare the resource.
            /// </summary>
            private void SetUnknownResourceState(TResource resource)
            {
                Requires.NotNull(resource, nameof(resource));

                lock (this.service.SyncObject)
                {
                    this.resourcePreparationStates.TryGetValue(resource, out ResourcePreparationTaskState? previousState);
                    this.resourcePreparationStates[resource] = ResourcePreparationTaskState.Create(
                        _ => previousState?.InnerTask ?? Task.CompletedTask,
                        ResourceState.Unknown,
                        CancellationToken.None).PreparationState;
                }
            }
예제 #4
0
        public List <TResource> ReadResourceList <TResource>() where TResource : Resources.GMResource, new()
        {
            int count = ReadInt32();
            var list  = new List <TResource>(count);

            for (int i = 0; i < count; i++)
            {
                var element = new TResource();
                element.ReadFrom(this);

                list.Add(element);
            }

            return(list);
        }
예제 #5
0
            /// <summary>
            /// Marks a resource as having been retrieved under a lock.
            /// </summary>
            internal void SetResourceAsAccessed(TResource resource)
            {
                Requires.NotNull(resource, nameof(resource));

                // Capture the ambient lock and use it for the two lock checks rather than
                // call AsyncReaderWriterLock.IsWriteLockHeld and IsUpgradeableReadLockHeld
                // to reduce the number of slow AsyncLocal<T>.get_Value calls we make.
                // Also do it before we acquire the lock, since a lock isn't necessary.
                // (verified to be a perf bottleneck in ETL traces).
                var ambientLock = this.service.AmbientLock;

                lock (this.service.SyncObject)
                {
                    if (!ambientLock.HasWriteLock && ambientLock.HasUpgradeableReadLock)
                    {
                        this.resourcesAcquiredWithinUpgradeableRead.Add(resource);
                    }
                }
            }
예제 #6
0
        public ActionResult <FileStream> Get(string id)
        {
            // if (!resourceServer.VerifyResourceId(id))
            //     throw new ResultException(404, "找不到资源");
            // string res_info = resourceServer.DecryptResourceId(id);
            TResource res_info = resourceServer.Retrieve(new TResource()
            {
                ResourceId = id
            });

            if (res_info == null)
            {
                Response.StatusCode = 404;
                return(null);
            }

            Response.ContentType = res_info.ContentType;
            return(resourceServer.RetrieveResourceFile(id));
        }
예제 #7
0
        /// <summary>
        /// 通过id获取文件流
        /// </summary>
        /// <param name="id">资源id</param>
        /// <returns>文件流</returns>
        FileStream IResource.RetrieveResourceFile(string id)
        {
            TResource res = m_resource.Retrieve(new TResource()
            {
                ResourceId = id
            });
            TType type = m_type.Retrieve(new TType()
            {
                TypeId = res.TypeId
            });

            string filepath = m_config["Resource:Path:" + type.Name] + "/" + res.Value;

            if (!File.Exists(filepath))
            {
                return(null);
            }

            return(File.OpenRead(filepath));
        }
예제 #8
0
        /// <summary>
        /// 上传文件
        /// </summary>
        /// <param name="type">类型信息</param>
        /// <param name="file">文件数据</param>
        /// <returns>ID</returns>
        string IResource.Upload(TType type, IFormFile file, string contentType)
        {
            string ex_name  = file.FileName.Substring(file.FileName.LastIndexOf('.'));
            string filename = Guid.NewGuid().ToString();
            string filepath = m_config["Resource:Path:" + type.Name] + "/" + filename + ex_name;

            //if (File.Exists(filepath))
            using (FileStream fs_file = File.Create(filepath))
            {
                file.CopyTo(fs_file);
            }
            Random    rand = new Random((int)Tools.Ticks());
            TResource res  = new TResource();

            res.ResourceId  = type.TypeId + "" + Tools.Ticks() + "-" + rand.Next(1000, 10000);
            res.Value       = filename + ex_name;
            res.TypeId      = type.TypeId;
            res.ContentType = contentType;
            m_resource.Create(res);

            return(res.ResourceId);
        }
예제 #9
0
        public void Display(TResource Res)
        {
            if (Res == null)
            {
                return;
            }
            label1.Text = string.Format("{0}/{1}", Res.CurrAmount, Res.Capacity);
            label3.Text = string.Format("({0:0}, {1}:{2:00}:{3:00})", Res.Produce,
                                        Math.Floor(Res.LeftTime.TotalHours),
                                        Res.LeftTime.Minutes, Res.LeftTime.Seconds);
            int color = Math.Abs(Convert.ToInt32(Res.LeftTime.TotalHours * 10));

            if (color > 255)
            {
                color = 255;
            }

            label3.ForeColor = Color.FromArgb(255 - color, 0, 0);
            label5.Text      = string.Format("({0}, {1:F2}%)", Res.Capacity - Res.CurrAmount, Res.CurrAmount * 100.0 / Res.Capacity);
            color            = Math.Abs(Res.CurrAmount * 255 / Res.Capacity);
            label5.ForeColor = Color.FromArgb(color, 0, 255 - color);
        }
 public AddResourceMessage(TResource resource, TaskCompletionSource <bool> resultTaskCompletionSource)
 {
     Resource = resource;
     ResultTaskCompletionSource = resultTaskCompletionSource;
 }
예제 #11
0
 public Resource(TResource value)
 {
     Value            = value;
     _referencesCount = 0;
 }
예제 #12
0
 public static TimestampedResource Create(TResource resource)
 {
     return(new TimestampedResource(resource, DateTime.Now));
 }
예제 #13
0
 /// <summary>
 /// 根据ID获取数据
 /// </summary>
 /// <param name="t">HuobiProject.Models</param>
 /// <returns>
 /// Success:T
 /// Failed:NULL
 /// </returns>
 TResource ICURD <TResource> .Retrieve(TResource t)
 {
     return(m_db.TResource.Find(t.ResourceId));
 }
            /// <summary>
            /// Prepares the specified resource for access by a lock holder.
            /// </summary>
            /// <param name="resource">The resource to prepare.</param>
            /// <param name="cancellationToken">The token whose cancellation signals lost interest in this resource.</param>
            /// <param name="forcePrepareConcurrent">Force preparation of the resource for concurrent access, even if an exclusive lock is currently held.</param>
            /// <returns>A task that is completed when preparation has completed.</returns>
            private Task PrepareResourceAsync(TResource resource, CancellationToken cancellationToken, bool forcePrepareConcurrent = false)
            {
                Requires.NotNull(resource, nameof(resource));
                Assumes.True(Monitor.IsEntered(this.service.SyncObject));

                // We deliberately ignore the cancellation token in the tasks we create and save because the tasks can be shared
                // across requests and we can't have task continuation chains where tasks within the chain get canceled
                // as that can cause premature starting of the next task in the chain.
                bool forConcurrentUse = forcePrepareConcurrent || !this.service.IsWriteLockHeld;

                AsyncReaderWriterResourceLock <TMoniker, TResource> .Helper.ResourceState finalState = forConcurrentUse ? ResourceState.Concurrent : ResourceState.Exclusive;

                Task?preparationTask = null;

                if (!this.resourcePreparationStates.TryGetValue(resource, out ResourcePreparationTaskState? preparationState))
                {
                    Func <object, Task>?preparationDelegate = forConcurrentUse
                        ? this.prepareResourceConcurrentDelegate
                        : this.prepareResourceExclusiveDelegate;

                    // We kick this off on a new task because we're currently holding a private lock
                    // and don't want to execute arbitrary code.
                    // Let's also hide the ARWL from the delegate if this is a shared lock request.
                    using (forConcurrentUse ? this.service.HideLocks() : default(Suppression))
                    {
                        // We can't currently use the caller's cancellation token for this task because
                        // this task may be shared with others or call this method later, and we wouldn't
                        // want their requests to be cancelled as a result of this first caller cancelling.
                        (preparationState, preparationTask) = ResourcePreparationTaskState.Create(
                            combinedCancellationToken => Task.Factory.StartNew(
                                NullableHelpers.AsNullableArgFunc(preparationDelegate),
                                forConcurrentUse ? Tuple.Create(resource, combinedCancellationToken) : Tuple.Create(resource, this.service.GetAggregateLockFlags(), combinedCancellationToken),
                                combinedCancellationToken,
                                TaskCreationOptions.None,
                                TaskScheduler.Default).Unwrap(),
                            finalState,
                            cancellationToken);
                    }
                }
                else
                {
                    Func <Task, object, Task>?preparationDelegate = null;
                    if (preparationState.State != finalState || preparationState.InnerTask.IsFaulted)
                    {
                        preparationDelegate = forConcurrentUse
                            ? this.prepareResourceConcurrentContinuationDelegate
                            : this.prepareResourceExclusiveContinuationDelegate;
                    }
                    else if (!preparationState.TryJoinPrepationTask(out preparationTask, cancellationToken))
                    {
                        preparationDelegate = forConcurrentUse
                            ? this.prepareResourceConcurrentContinuationOnPossibleCancelledTaskDelegate
                            : this.prepareResourceExclusiveContinuationOnPossibleCancelledTaskDelegateDelegate;
                    }

                    if (preparationTask is null)
                    {
                        Assumes.NotNull(preparationDelegate);

                        // We kick this off on a new task because we're currently holding a private lock
                        // and don't want to execute arbitrary code.
                        // Let's also hide the ARWL from the delegate if this is a shared lock request.
                        using (forConcurrentUse ? this.service.HideLocks() : default(Suppression))
                        {
                            (preparationState, preparationTask) = ResourcePreparationTaskState.Create(
                                combinedCancellationToken => preparationState.InnerTask.ContinueWith(
                                    preparationDelegate !,
                                    forConcurrentUse ? Tuple.Create(resource, combinedCancellationToken) : Tuple.Create(resource, this.service.GetAggregateLockFlags(), combinedCancellationToken),
                                    CancellationToken.None,
                                    TaskContinuationOptions.RunContinuationsAsynchronously,
                                    TaskScheduler.Default).Unwrap(),
                                finalState,
                                cancellationToken);
                        }
                    }
                }

                Assumes.NotNull(preparationState);
                this.resourcePreparationStates[resource] = preparationState;

                return(preparationTask);
            }
예제 #15
0
 public Slot(ResourcePool <TResource> pool)
 {
     this._pool     = pool;
     this._resource = new TResource();
 }
예제 #16
0
 public UsingEnumerator(IAsyncEnumerator <TSource> source, TResource resource, Action <TResource> resourceCleanup)
 {
     _source          = source;
     _resource        = resource;
     _resourceCleanup = resourceCleanup;
 }
 public static TimestampedResource Create(TResource resource)
 => new TimestampedResource(resource, DateTime.Now);
 public ResourceAvailableMessage(TResource resource)
 {
     Resource = resource;
 }
예제 #19
0
 public ResourceCount(TResource resource)
 {
     this.Resource   = resource;
     this.UsageCount = 0;
 }
 private TimestampedResource(TResource resource, DateTime created)
 {
     Resource = resource;
     Created  = created;
 }
예제 #21
0
 /// <summary>
 ///     Initializes a new instance of the <see cref="Wrapper" /> struct.
 /// </summary>
 /// <param name="resource">The resource.</param>
 /// <param name="isTemp">if set to <see langword="true" /> the resourec is only temporary.</param>
 public Wrapper([NotNull] TResource resource, bool isTemp)
 {
     Debug.Assert(resource != null, "resource != null");
     _resource   = resource;
     IsTemporary = isTemp;
 }