예제 #1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="MockAsyncServiceProvider"/> class.
        /// </summary>
        /// <param name="serviceProvider">The root of all services.</param>
        internal MockAsyncServiceProvider(OLE.Interop.IServiceProvider serviceProvider)
        {
            this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider));

            this.taskSchedulerService = (IVsTaskSchedulerService)serviceProvider.QueryService(typeof(SVsTaskSchedulerService).GUID);
            Assumes.Present(this.taskSchedulerService);
        }
        /// <summary>
        /// Executes a non-cancellable operation in the specified <see cref="VsTaskRunContext"/> and doesn't wait until it is completed
        /// </summary>
        /// <param name="serviceProvider">An instance of <see cref="IServiceProvider"/>. Required.</param>
        /// <param name="context">The <see cref="VsTaskRunContext"/> in which to run the operation</param>
        /// <param name="op">The operation to run</param>
        internal static void BeginTask(IServiceProvider serviceProvider, VsTaskRunContext context, Action op)
        {
            Debug.Assert(serviceProvider != null, "IServiceProvider is required");
            Debug.Assert(op != null, "Action is required");
            IVsTaskSchedulerService taskService = serviceProvider.GetService(typeof(SVsTaskSchedulerService)) as IVsTaskSchedulerService;
            IVsTaskBody             body        = VsTaskLibraryHelper.CreateTaskBody(op);
            IVsTask task = VsTaskLibraryHelper.CreateTask(taskService, context, VsTaskCreationOptions.NotCancelable, body, null);

            task.Start();
        }
        /// <summary>
        /// Runs <paramref name="idleWork"/> over each item in <paramref name="workQueue"/> on the UI Thread during idle time.
        /// This method will keep iterating through <paramref name="workQueue"/> on the same idle loop while VS remains idle.
        /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
        /// </summary>
        /// <typeparam name="T">The type of the data to be processed.</typeparam>
        /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
        /// <param name="idleWork">Action to run on idle.</param>
        /// <param name="workQueue">Data to process on idle.</param>
        /// <param name="token">Cancellation token to indicate when the work is no longer needed.</param>
        /// <returns
        /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
        /// either all of the work in workQueue has been processed, or the operation was canceled.
        /// </returns>
        public static Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, ConcurrentQueue <T> workQueue, CancellationToken token)
        {
            // Check for good data
            if (idleWork == null)
            {
                throw new ArgumentNullException(nameof(idleWork));
            }

            if (workQueue == null)
            {
                throw new ArgumentNullException(nameof(workQueue));
            }

            return(@this.RunOnIdleAsync(idleWork, workQueue.TryDequeue, token));
        }
        /// <summary>
        /// Creates a <see cref="IVsTask"/> in the specified <see cref="VsTaskRunContext"/>
        /// </summary>
        /// <param name="serviceProvider">An instance of <see cref="IServiceProvider"/>. Required.</param>
        /// <param name="context">The <see cref="VsTaskRunContext"/> in which to run the operation</param>
        /// <param name="op">The operation to run</param>
        /// <param name="token">Option cancellation token <see cref="CancellationToken"/></param>
        /// <returns>An await-able object that returns a result</returns>
        private static IVsTask CreateTask <T>(IServiceProvider serviceProvider, VsTaskRunContext context, Func <T> op, CancellationToken token)
        {
            Debug.Assert(serviceProvider != null, "IServiceProvider is required");
            Debug.Assert(op != null, "op is required");

            IVsTaskSchedulerService taskService = serviceProvider.GetService(typeof(SVsTaskSchedulerService)) as IVsTaskSchedulerService;
            IVsTaskBody             body        = VsTaskLibraryHelper.CreateTaskBody(() => (object)op());
            IVsTask task = VsTaskLibraryHelper.CreateTask(taskService, context, body);

            if (token != CancellationToken.None)
            {
                task.ApplyCancellationToken(token);
            }

            return(task);
        }
        /// <summary>
        /// Runs <paramref name="idleWork"/> over each item in <paramref name="workData"/> on the UI Thread during idle time.
        /// This method will keep iterating through <paramref name="workData"/> on the same idle loop while VS remains idle.
        /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
        /// </summary>
        /// <typeparam name="T">The type of the data to be processed.</typeparam>
        /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
        /// <param name="idleWork">Action to run on idle.</param>
        /// <param name="workData">Data to process on idle.</param>
        /// <param name="token">Cancellation token to indicate when the work is no longer needed.</param>
        /// <returns
        /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
        /// either all of the work in workData has been processed, or the operation was canceled.
        /// </returns>
        public static Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, IEnumerable <T> workData, CancellationToken token)
        {
            // Check for good data
            if (idleWork == null)
            {
                throw new ArgumentNullException(nameof(idleWork));
            }

            if (workData == null)
            {
                throw new ArgumentNullException(nameof(workData));
            }

            // Make a copy of the items since we're going to be iterating over them across multiple dispatcher operations.
            T[] items   = workData.ToArray();
            var adapter = new TryGetNextItemEnumerableAdapter <T>(items);

            return(@this.RunOnIdleAsync(idleWork, adapter.TryGetNextItem, token));
        }
        /// <summary>
        /// Runs <paramref name="idleWork"/> over each item returned from <paramref name="tryGetNextItem"/> on the UI Thread during idle time.
        /// This method will keep processing data from <paramref name="tryGetNextItem" /> on the same idle loop while VS remains idle.
        /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
        /// </summary>
        /// <typeparam name="T">The type of the data to be processed.</typeparam>
        /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
        /// <param name="idleWork">Action to run on idle.</param>
        /// <param name="tryGetNextItem">Delegate used to get the next piece of data to process.  tryGetNextItem should return true
        /// when another item is available and false when there is no more data to process.</param>
        /// <param name="token">Cancellation token to indicate when the work is no longer needed.</param>
        /// <returns>
        /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
        /// either all of the work received from tryGetNextItem has been processed, or the operation was canceled.
        /// </returns>
        public static async Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, TryGetNextItem <T> tryGetNextItem, CancellationToken token)
        {
            // Check for good data
            if (idleWork == null)
            {
                throw new ArgumentNullException(nameof(idleWork));
            }

            if (tryGetNextItem == null)
            {
                throw new ArgumentNullException(nameof(tryGetNextItem));
            }

            Stopwatch stopwatch = new Stopwatch();

            T data;

            while (tryGetNextItem(out data))
            {
                token.ThrowIfCancellationRequested();

                await VsTaskLibraryHelper.CreateAndStartTask(
                    @this,
                    VsTaskRunContext.UIThreadIdlePriority,
                    VsTaskLibraryHelper.CreateTaskBody(() =>
                {
                    stopwatch.Start();

                    do
                    {
                        // Ensure cancellation occurring between work items is respected
                        token.ThrowIfCancellationRequested();
                        idleWork(data);
                    }while (stopwatch.ElapsedMilliseconds < MaxMillisecondIdleTime && tryGetNextItem(out data));

                    stopwatch.Stop();
                }));

                stopwatch.Reset();
            }
        }
 /// <summary>
 /// Runs <paramref name="idleWork"/> over each item in <paramref name="workData"/> on the UI Thread during idle time.
 /// This method will keep iterating through <paramref name="workData"/> on the same idle loop while VS remains idle.
 /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
 /// </summary>
 /// <typeparam name="T">The type of the data to be processed.</typeparam>
 /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
 /// <param name="idleWork">Action to run on idle.</param>
 /// <param name="workData">Data to process on idle.</param>
 /// <returns
 /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
 /// either all of the work in workData has been processed, or the operation was canceled.
 /// </returns>
 public static Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, IEnumerable <T> workData)
 {
     return(@this.RunOnIdleAsync <T>(idleWork, workData, CancellationToken.None));
 }
 /// <summary>
 /// Runs <paramref name="idleWork"/> over each item returned from <paramref name="tryGetNextItem"/> on the UI Thread during idle time.
 /// This method will keep processing data from <paramref name="tryGetNextItem" /> on the same idle loop while VS remains idle.
 /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
 /// </summary>
 /// <typeparam name="T">The type of the data to be processed.</typeparam>
 /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
 /// <param name="idleWork">Action to run on idle.</param>
 /// <param name="tryGetNextItem">Delegate used to get the next piece of data to process.  tryGetNextItem should return true
 /// when another item is available and false when there is no more data to process.</param>
 /// <returns>
 /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
 /// either all of the work received from tryGetNextItem has been processed, or the operation was canceled.
 /// </returns>
 public static Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, TryGetNextItem <T> tryGetNextItem)
 {
     return(@this.RunOnIdleAsync <T>(idleWork, tryGetNextItem, CancellationToken.None));
 }
 /// <summary>
 /// Runs <paramref name="idleWork"/> over each item in <paramref name="workQueue"/> on the UI Thread during idle time.
 /// This method will keep iterating through <paramref name="workQueue"/> on the same idle loop while VS remains idle.
 /// Once VS is no longer idle, the method will yield control and pick up where it left off on the next idle loop.
 /// </summary>
 /// <typeparam name="T">The type of the data to be processed.</typeparam>
 /// <param name="this">The IVsTaskSchedulerService to use when scheduling the work.</param>
 /// <param name="idleWork">Action to run on idle.</param>
 /// <param name="workQueue">Data to process on idle.</param>
 /// <returns
 /// >A task representing all of the asynchronous work this method is performing.  When the task is marked as completed,
 /// either all of the work in workQueue has been processed, or the operation was canceled.
 /// </returns>
 public static Task RunOnIdleAsync <T>(this IVsTaskSchedulerService @this, Action <T> idleWork, ConcurrentQueue <T> workQueue)
 {
     return(@this.RunOnIdleAsync <T>(idleWork, workQueue, CancellationToken.None));
 }
예제 #10
0
 static ProjectFactory()
 {
     ThreadHelper.ThrowIfNotOnUIThread();
     taskSchedulerService = Microsoft.VisualStudio.Shell.Package.GetGlobalService(typeof(SVsTaskSchedulerService)) as IVsTaskSchedulerService;
 }