using System;
namespace ScheduleWork
{
public interface IScheduleWork
{
bool IsRun
{
get;
}
bool IsCompleted
{
get;
}
bool IsFailed
{
get;
}
Exception FailedException
{
get;
}
bool IsFailedRollback
{
get;
set;
}
float Progress
{
get;
}
IScheduleWork Start();
IScheduleWork Stop();
IScheduleWork Wait();
void Rollback();
}
}
using System;
using System.Threading;
using System.Threading.Tasks;
namespace ScheduleWork
{
public abstract class ScheduleWorkBase : IScheduleWork
{
private float progress = 0f;
public Action<float> UpdateProgressAction;
public Action<IScheduleWork> CompletedAction;
public virtual object Result
{
get;
protected set;
}
public bool IsRun
{
get;
private set;
}
public bool IsCompleted
{
get;
protected set;
}
public bool IsFailed
{
get;
protected set;
}
public Exception FailedException
{
get;
protected set;
}
public bool IsFailedRollback
{
get;
set;
}
public float Progress
{
get
{
return this.progress;
}
set
{
if (this.progress != value)
{
this.progress = value;
this.UpdateProgress();
}
}
}
public Task CurrentTask
{
get;
protected set;
}
public CancellationTokenSource TokenSource
{
get;
protected set;
}
public ScheduleWorkBase()
{
this.Progress = 0f;
this.IsCompleted = false;
this.IsFailed = false;
this.IsFailedRollback = true;
}
public IScheduleWork Start()
{
return this.Start(null);
}
public IScheduleWork Start(Action<IScheduleWork> complete)
{
if (this.IsRun)
{
throw new InvalidOperationException("IsRun: True");
}
this.Progress = 0f;
this.IsCompleted = false;
this.IsFailed = false;
if (complete != null)
{
this.CompletedAction = (Action<IScheduleWork>)Delegate.Combine(this.CompletedAction, complete);
}
this.TokenSource = new CancellationTokenSource();
this.CurrentTask = Task.Factory.StartNew(new Action(this.RunWorkingWrapping), this.TokenSource.Token);
this.CurrentTask.ContinueWith(new Action<Task>(this.Completed));
return this;
}
public IScheduleWork Stop()
{
if (!this.IsRun)
{
throw new InvalidOperationException("IsRun: False");
}
if (this.TokenSource != null)
{
this.TokenSource.Cancel();
}
return this;
}
public IScheduleWork Wait()
{
try
{
this.CurrentTask.Wait();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
return this;
}
public virtual void Rollback()
{
}
protected void RunWorkingWrapping()
{
try
{
this.IsRun = true;
this.Result = this.RunWorking();
}
catch (Exception e)
{
this.IsFailed = true;
this.FailedException = e;
if (this.IsFailedRollback)
{
this.Rollback();
}
}
finally
{
this.IsCompleted = true;
this.IsRun = false;
}
}
protected abstract object RunWorking();
protected void UpdateProgress()
{
if (this.UpdateProgressAction != null)
{
this.UpdateProgressAction(this.Progress);
}
}
protected void Completed(Task t)
{
if (this.CompletedAction != null)
{
this.CompletedAction(this);
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
namespace ScheduleWork
{
public class CollectionScheduleWork : ScheduleWorkBase
{
private IList<ScheduleWorkBase> AllWork;
private IList<ScheduleWorkBase> CompletedWork;
public override object Result
{
get
{
return (
from m in this.CompletedWork
select m.Result).ToList<object>();
}
protected set
{
}
}
public CollectionScheduleWork()
{
this.AllWork = new List<ScheduleWorkBase>();
this.CompletedWork = new List<ScheduleWorkBase>();
}
protected override object RunWorking()
{
this.CompletedWork.Clear();
foreach (ScheduleWorkBase item in this.AllWork)
{
item.Start();
item.CurrentTask.Wait();
if (item.IsFailed)
{
throw item.FailedException;
}
this.CompletedWork.Add(item);
}
return (
from c in this.CompletedWork
select c.Result).ToList<object>();
}
public void AddScheduleWork(ScheduleWorkBase scheduleWork)
{
if (base.IsRun || base.IsCompleted)
{
throw new InvalidOperationException("IsRun || IsCompleted");
}
this.AllWork.Add(scheduleWork);
}
public override void Rollback()
{
Console.WriteLine("CollectionScheduleWork.Rollback");
foreach (ScheduleWorkBase item in this.CompletedWork)
{
item.Rollback();
}
}
}
}
using System;
namespace ScheduleWork
{
public class DelegateScheduleWork : ScheduleWorkBase
{
public Func<ScheduleWorkBase, object> ScheduleWorkAction;
public Func<ScheduleWorkBase, bool> RollbackAction;
public DelegateScheduleWork(Func<ScheduleWorkBase, object> action, Func<ScheduleWorkBase, bool> rollback)
{
this.ScheduleWorkAction = action;
this.RollbackAction = rollback;
}
public DelegateScheduleWork(Func<ScheduleWorkBase, object> action) : this(action, null)
{
}
protected override object RunWorking()
{
object result;
if (this.ScheduleWorkAction != null)
{
result = this.ScheduleWorkAction(this);
}
else
{
result = null;
}
return result;
}
public override void Rollback()
{
if (this.RollbackAction != null)
{
this.RollbackAction(this);
}
}
}
}
using System;
namespace ScheduleWork
{
public class ScheduleWorkEventArgs : EventArgs
{
public bool IsCompleted
{
get
{
return this.Target.IsCompleted;
}
}
public bool IsFailed
{
get
{
return this.Target.IsFailed;
}
}
public IScheduleWork Target
{
get;
private set;
}
public ScheduleWorkEventArgs(IScheduleWork target)
{
this.Target = target;
}
}
}