| File: Plugins\InboundRequestProcessingHandler.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Protocol\NuGet.Protocol.csproj (NuGet.Protocol) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Linq; using System.Threading; using System.Threading.Tasks; namespace NuGet.Protocol.Plugins { internal class InboundRequestProcessingHandler : IDisposable { private readonly ISet<MessageMethod> _fastProccessingMethods; private readonly Lazy<DedicatedAsynchronousProcessingThread> _processingThread; private bool _isDisposed; public InboundRequestProcessingHandler() : this(Enumerable.Empty<MessageMethod>()) { } /// <summary> /// Requests from the processing methods provided in this set are handled on a dedicated thread. /// </summary> /// <param name="fastProcessingMethods"></param> public InboundRequestProcessingHandler(IEnumerable<MessageMethod> fastProcessingMethods) { if (fastProcessingMethods == null) { throw new ArgumentNullException(nameof(fastProcessingMethods)); } _fastProccessingMethods = new HashSet<MessageMethod>(fastProcessingMethods); // Lazily initialize the processing thread. It is not needed if there are no time critical methods. _processingThread = new Lazy<DedicatedAsynchronousProcessingThread>(() => { var thread = new DedicatedAsynchronousProcessingThread(TimeSpan.FromMilliseconds(50)); thread.Start(); return thread; }); } /// <summary> /// Methods that are in the fast processing method list will be handled on a separate thread. Everything else will be queued on the threadpool. /// </summary> /// <param name="messageMethod"></param> /// <param name="task"></param> /// <param name="cancellationToken"></param> internal void Handle(MessageMethod messageMethod, Func<Task> task, CancellationToken cancellationToken) { ThrowIfDisposed(); if (_fastProccessingMethods.Contains(messageMethod)) { _processingThread.Value.Enqueue(task); } else { Task.Run(task, cancellationToken); } } public void Dispose() { if (_isDisposed) { return; } if (_processingThread.IsValueCreated) { _processingThread.Value.Dispose(); } GC.SuppressFinalize(this); _isDisposed = true; } private void ThrowIfDisposed() { if (_isDisposed) { throw new ObjectDisposedException(GetType().Name); } } } }