using ServerManagerTool.Common.Interfaces;
using System;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
namespace ServerManagerTool.Common.Lib
{
///
/// This class ensures the following:
/// 1. All work items run in the order posted.
/// 2. Work items run on a background thread.
/// 3. Work items do not overlap
/// 4. If requested, the completion status of a work item is returned via a task.
///
public class ActionQueue : IAsyncDisposable
{
public ActionBlock workQueue;
public ActionQueue(TaskScheduler scheduler = null)
{
this.workQueue = new ActionBlock(a => a.Invoke(), new ExecutionDataflowBlockOptions { MaxDegreeOfParallelism = 1, TaskScheduler = scheduler ?? TaskScheduler.Default });
}
public Task PostAction(Func action)
{
TaskCompletionSource tcs = new TaskCompletionSource();
this.workQueue.Post(() =>
{
try
{
var result = action.Invoke();
Task.Run(() => tcs.TrySetResult(result));
}
catch(Exception ex)
{
Task.Run(() => tcs.TrySetException(ex));
}
});
return tcs.Task;
}
public Task PostAction(Action action)
{
return PostAction(() => { action.Invoke(); return true; });
}
public async Task DisposeAsync()
{
await PostAction(() => this.workQueue.Complete());
}
}
}