From e7d3fe2beae326a2380b4cfed7f33961f40d87ca Mon Sep 17 00:00:00 2001 From: Sergey Chebotar Date: Thu, 11 Nov 2021 16:33:40 +0300 Subject: Init commit --- ExcelTaskUtil.cs | 133 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 ExcelTaskUtil.cs (limited to 'ExcelTaskUtil.cs') diff --git a/ExcelTaskUtil.cs b/ExcelTaskUtil.cs new file mode 100644 index 0000000..c7d1b94 --- /dev/null +++ b/ExcelTaskUtil.cs @@ -0,0 +1,133 @@ +using ExcelDna.Integration; +using System.Threading.Tasks; +using System; +using System.Threading; + +namespace Rehau.Sku.Assist +{ + internal static class ExcelTaskUtil + { + public static object Run(string callerFunctionName, object callerParameters, Func> taskSource) + { + return ExcelAsyncUtil.Observe(callerFunctionName, callerParameters, delegate + { + var cts = new CancellationTokenSource(); + var task = taskSource(cts.Token); + return new ExcelTaskObservable(task, cts); + }); + } + + public static object Run(string callerFunctionName, object callerParameters, Func> taskSource) + { + return ExcelAsyncUtil.Observe(callerFunctionName, callerParameters, delegate + { + var task = taskSource(); + return new ExcelTaskObservable(task); + }); + } + + class ExcelTaskObservable : IExcelObservable + { + readonly Task _task; + readonly CancellationTokenSource _cts; + public ExcelTaskObservable(Task task) + { + _task = task; + } + + public ExcelTaskObservable(Task task, CancellationTokenSource cts) + : this(task) + { + _cts = cts; + } + + public IDisposable Subscribe(IExcelObserver observer) + { + switch (_task.Status) + { + case TaskStatus.RanToCompletion: + observer.OnNext(_task.Result); + observer.OnCompleted(); + break; + case TaskStatus.Faulted: + observer.OnError(_task.Exception.InnerException); + break; + case TaskStatus.Canceled: + observer.OnError(new TaskCanceledException(_task)); + break; + default: + _task.ContinueWith(t => + { + switch (t.Status) + { + case TaskStatus.RanToCompletion: + observer.OnNext(t.Result); + observer.OnCompleted(); + break; + case TaskStatus.Faulted: + observer.OnError(t.Exception.InnerException); + break; + case TaskStatus.Canceled: + observer.OnError(new TaskCanceledException(t)); + break; + } + }); + break; + } + + if (_cts != null) + { + return new CancellationDisposable(_cts); + } + + return DefaultDisposable.Instance; + } + } + + sealed class DefaultDisposable : IDisposable + { + + public static readonly DefaultDisposable Instance = new DefaultDisposable(); + + DefaultDisposable() + { + } + + public void Dispose() + { + } + } + + sealed class CancellationDisposable : IDisposable + { + + readonly CancellationTokenSource cts; + public CancellationDisposable(CancellationTokenSource cts) + { + if (cts == null) + { + throw new ArgumentNullException("cts"); + } + + this.cts = cts; + } + + public CancellationDisposable() + : this(new CancellationTokenSource()) + { + } + + public CancellationToken Token + { + get { return cts.Token; } + } + + public void Dispose() + { + cts.Cancel(); + } + } + + } +} + -- cgit v1.2.3