How to write unit tests with TPL and TaskScheduler

后端 未结 5 1556
离开以前
离开以前 2021-02-01 06:50

Imagine a function like this:

private static ConcurrentList list = new ConcurrentList();
public void Add(object x)
{
   Task.Factory.         


        
      
      
      
5条回答
  •  抹茶落季
    2021-02-01 07:16

    The solution that worked for me was to send the TaskScheduler as a dependency to the code I want to unit test (e.g.

    MyClass(TaskScheduler asyncScheduler, TaskScheduler guiScheduler)
    

    Where asyncScheduler is used to schedule tasks that run on worker threads (blocking calls) and guiScheduler is used to schedule tasks that should run on GUI (non blocking calls).

    In the unit test, I would then inject a specific schedulers, i.e. CurrentThreadTaskScheduler instances. CurrentThreadTaskScheduler is a scheduler implementation that runs the tasks immediately, instead of queuing them.

    You can find the implementation in the Microsoft Samples for Parallel Programming here.

    I'll paste the code for quick reference:

    /// Provides a task scheduler that runs tasks on the current thread.
    public sealed class CurrentThreadTaskScheduler : TaskScheduler
    {
        /// Runs the provided Task synchronously on the current thread.
        /// The task to be executed.
        protected override void QueueTask(Task task)
        {
            TryExecuteTask(task);
        }
    
        /// Runs the provided Task synchronously on the current thread.
        /// The task to be executed.
        /// Whether the Task was previously queued to the scheduler.
        /// True if the Task was successfully executed; otherwise, false.
        protected override bool TryExecuteTaskInline(Task task, bool taskWasPreviouslyQueued)
        {
            return TryExecuteTask(task);
        }
    
        /// Gets the Tasks currently scheduled to this scheduler.
        /// An empty enumerable, as Tasks are never queued, only executed.
        protected override IEnumerable GetScheduledTasks()
        {
            return Enumerable.Empty();
        }
    
        /// Gets the maximum degree of parallelism for this scheduler.
        public override int MaximumConcurrencyLevel { get { return 1; } }
    }
    

提交回复
热议问题