mirror of
https://github.com/esiur/esiur-dotnet.git
synced 2026-04-04 12:28:21 +00:00
Layout
This commit is contained in:
52
Libraries/Esiur/Core/AsyncAwaiter.cs
Normal file
52
Libraries/Esiur/Core/AsyncAwaiter.cs
Normal file
@@ -0,0 +1,52 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncAwaiter : INotifyCompletion
|
||||
{
|
||||
Action callback = null;
|
||||
|
||||
AsyncException exception = null;
|
||||
|
||||
object result;
|
||||
|
||||
|
||||
public AsyncAwaiter(AsyncReply reply)
|
||||
{
|
||||
reply.Then(x =>
|
||||
{
|
||||
this.IsCompleted = true;
|
||||
this.result = x;
|
||||
this.callback?.Invoke();
|
||||
}).Error(x =>
|
||||
{
|
||||
exception = x;
|
||||
this.IsCompleted = true;
|
||||
this.callback?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
public object GetResult()
|
||||
{
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsCompleted { get; private set; }
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
if (IsCompleted)
|
||||
continuation?.Invoke();
|
||||
else
|
||||
// Continue....
|
||||
callback = continuation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
50
Libraries/Esiur/Core/AsyncAwaiterGeneric.cs
Normal file
50
Libraries/Esiur/Core/AsyncAwaiterGeneric.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncAwaiter<T> : INotifyCompletion
|
||||
{
|
||||
Action callback = null;
|
||||
|
||||
AsyncException exception = null;
|
||||
|
||||
T result;
|
||||
|
||||
public AsyncAwaiter(AsyncReply<T> reply)
|
||||
{
|
||||
reply.Then(x =>
|
||||
{
|
||||
this.IsCompleted = true;
|
||||
this.result = (T)x;
|
||||
this.callback?.Invoke();
|
||||
}).Error(x =>
|
||||
{
|
||||
exception = x;
|
||||
this.IsCompleted = true;
|
||||
this.callback?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
public T GetResult()
|
||||
{
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsCompleted { get; private set; }
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
if (IsCompleted)
|
||||
continuation?.Invoke();
|
||||
else
|
||||
// Continue....
|
||||
callback = continuation;
|
||||
}
|
||||
|
||||
}
|
||||
159
Libraries/Esiur/Core/AsyncBag.cs
Normal file
159
Libraries/Esiur/Core/AsyncBag.cs
Normal file
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using Esiur.Data;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
interface IAsyncBag
|
||||
{
|
||||
public void Add(object replyOrValue);
|
||||
}
|
||||
|
||||
public class AsyncBag<T> : AsyncReply, IAsyncBag
|
||||
{
|
||||
|
||||
protected List<object> replies = new List<object>();
|
||||
//List<T> results = new();
|
||||
|
||||
int count = 0;
|
||||
bool sealedBag = false;
|
||||
|
||||
|
||||
public virtual Type ArrayType { get; set; } = typeof(T);
|
||||
|
||||
public AsyncBag<T> Then(Action<T[]> callback)
|
||||
{
|
||||
//if (!sealedBag && !resultReady)
|
||||
// throw new Exception("Not sealed");
|
||||
|
||||
//Timeout(6000, () =>
|
||||
//{
|
||||
//Console.WriteLine("Timeout " + count + this.Result);
|
||||
//});
|
||||
|
||||
base.Then(new Action<object>(o => callback((T[])o)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public new AsyncBagAwaiter<T> GetAwaiter()
|
||||
{
|
||||
return new AsyncBagAwaiter<T>(this);
|
||||
}
|
||||
|
||||
public new T[] Wait()
|
||||
{
|
||||
return (T[])base.Wait();
|
||||
}
|
||||
|
||||
public new T[] Wait(int timeout)
|
||||
{
|
||||
return (T[])base.Wait(timeout);
|
||||
}
|
||||
|
||||
public void Seal()
|
||||
{
|
||||
if (sealedBag)
|
||||
return;
|
||||
|
||||
sealedBag = true;
|
||||
|
||||
var results = ArrayType == null ? new T[replies.Count]
|
||||
: Array.CreateInstance(ArrayType, replies.Count);
|
||||
|
||||
if (replies.Count == 0)
|
||||
{
|
||||
Trigger(results);
|
||||
return;
|
||||
}
|
||||
|
||||
for (var i = 0; i < replies.Count; i++)
|
||||
{
|
||||
|
||||
var k = replies[i];
|
||||
var index = i;
|
||||
|
||||
if (k is AsyncReply reply)
|
||||
{
|
||||
reply.Then((r) =>
|
||||
{
|
||||
results.SetValue(r, index);
|
||||
count++;
|
||||
if (count == replies.Count)
|
||||
Trigger(results);
|
||||
}).Error(e => TriggerError(e));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ArrayType != null)
|
||||
replies[i] = RuntimeCaster.Cast(replies[i], ArrayType);
|
||||
|
||||
results.SetValue(replies[i], index);
|
||||
count++;
|
||||
if (count == replies.Count)
|
||||
Trigger(results);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Add(object valueOrReply)
|
||||
{
|
||||
if (!sealedBag)
|
||||
{
|
||||
//if (valueOrReply is AsyncReply)
|
||||
//{
|
||||
// results.Add(default(T));
|
||||
replies.Add(valueOrReply);
|
||||
//}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void AddBag(AsyncBag<T> bag)
|
||||
{
|
||||
foreach (var r in bag.replies)
|
||||
Add(r);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncBag()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public AsyncBag(T[] results)
|
||||
: base(results)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
51
Libraries/Esiur/Core/AsyncBagAwaiter.cs
Normal file
51
Libraries/Esiur/Core/AsyncBagAwaiter.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncBagAwaiter<T> : INotifyCompletion
|
||||
{
|
||||
Action callback = null;
|
||||
|
||||
AsyncException exception = null;
|
||||
|
||||
T[] result;
|
||||
|
||||
public AsyncBagAwaiter(AsyncBag<T> reply)
|
||||
{
|
||||
reply.Then(x =>
|
||||
{
|
||||
this.IsCompleted = true;
|
||||
this.result = x;
|
||||
this.callback?.Invoke();
|
||||
}).Error(x =>
|
||||
{
|
||||
exception = x;
|
||||
this.IsCompleted = true;
|
||||
this.callback?.Invoke();
|
||||
});
|
||||
}
|
||||
|
||||
public T[] GetResult()
|
||||
{
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
return result;
|
||||
}
|
||||
|
||||
public bool IsCompleted { get; private set; }
|
||||
|
||||
public void OnCompleted(Action continuation)
|
||||
{
|
||||
if (IsCompleted)
|
||||
continuation?.Invoke();
|
||||
else
|
||||
// Continue....
|
||||
callback = continuation;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
56
Libraries/Esiur/Core/AsyncException.cs
Normal file
56
Libraries/Esiur/Core/AsyncException.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncException : Exception
|
||||
{
|
||||
public readonly ErrorType Type;
|
||||
public readonly ExceptionCode Code;
|
||||
|
||||
public AsyncException(Exception exception) : base(exception.Message, exception)
|
||||
{
|
||||
Type = ErrorType.Exception;
|
||||
Code = 0;
|
||||
}
|
||||
|
||||
public override string StackTrace => InnerException != null && Type == ErrorType.Exception ? InnerException.StackTrace : base.StackTrace;
|
||||
|
||||
public AsyncException(ErrorType type, ushort code, string message)
|
||||
: base(type == ErrorType.Management ? ((ExceptionCode)code).ToString() : message)
|
||||
{
|
||||
this.Type = type;
|
||||
this.Code = (ExceptionCode)code;
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Code.ToString() + ": " + Message;
|
||||
}
|
||||
}
|
||||
147
Libraries/Esiur/Core/AsyncQueue.cs
Normal file
147
Libraries/Esiur/Core/AsyncQueue.cs
Normal file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public struct AsyncQueueItem<T>
|
||||
{
|
||||
public AsyncReply<T> Reply;
|
||||
public int Sequence;
|
||||
public DateTime Arrival;
|
||||
public DateTime Delivered;
|
||||
public DateTime Ready;
|
||||
public int BatchSize;
|
||||
public int FlushId;
|
||||
public int NotificationsCountWaitingInTheQueueAtEnqueueing;
|
||||
public bool HasResource;
|
||||
}
|
||||
|
||||
|
||||
public class AsyncQueue<T> : AsyncReply<T>
|
||||
{
|
||||
|
||||
int currentId = 0;
|
||||
int currentFlushId;
|
||||
|
||||
public List<AsyncQueueItem<T>> Processed = new();
|
||||
|
||||
List<AsyncQueueItem<T>> list = new List<AsyncQueueItem<T>>();
|
||||
//Action<T> callback;
|
||||
object queueLock = new object();
|
||||
|
||||
//public AsyncQueue<T> Then(Action<T> callback)
|
||||
//{
|
||||
// base.Then(new Action<object>(o => callback((T)o)));
|
||||
|
||||
//return this;
|
||||
//}
|
||||
|
||||
public void Add(AsyncReply<T> reply)
|
||||
{
|
||||
lock (queueLock)
|
||||
{
|
||||
currentId++;
|
||||
list.Add(new AsyncQueueItem<T>()
|
||||
{
|
||||
Sequence = currentId,
|
||||
NotificationsCountWaitingInTheQueueAtEnqueueing = list.Count,
|
||||
Reply = reply,
|
||||
Arrival = DateTime.Now,
|
||||
HasResource = !reply.Ready
|
||||
});
|
||||
}
|
||||
|
||||
resultReady = false;
|
||||
if (reply.Ready)
|
||||
processQueue(default(T));
|
||||
else
|
||||
reply.Then(processQueue);
|
||||
}
|
||||
|
||||
public void Remove(AsyncReply<T> reply)
|
||||
{
|
||||
lock (queueLock)
|
||||
{
|
||||
var item = list.FirstOrDefault(i => i.Reply == reply);
|
||||
list.Remove(item);
|
||||
}
|
||||
|
||||
processQueue(default(T));
|
||||
}
|
||||
|
||||
void processQueue(T o)
|
||||
{
|
||||
lock (queueLock)
|
||||
{
|
||||
var batchSize = 0;
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
{
|
||||
if (list[i].Reply.Ready)
|
||||
{
|
||||
batchSize++;
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var flushId = currentFlushId++;
|
||||
|
||||
for (var i = 0; i < list.Count; i++)
|
||||
if (list[i].Reply.Ready)
|
||||
{
|
||||
Trigger(list[i].Reply.Result);
|
||||
resultReady = false;
|
||||
|
||||
var p = list[i];
|
||||
p.Delivered = DateTime.Now;
|
||||
p.Ready = p.Reply.ReadyTime;
|
||||
p.BatchSize = batchSize;
|
||||
p.FlushId = flushId;
|
||||
//p.HasResource = p.Reply. (p.Ready - p.Arrival).TotalMilliseconds > 5;
|
||||
Processed.Add(p);
|
||||
|
||||
list.RemoveAt(i);
|
||||
|
||||
i--;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
resultReady = (list.Count == 0);
|
||||
}
|
||||
|
||||
public AsyncQueue()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
432
Libraries/Esiur/Core/AsyncReply.cs
Normal file
432
Libraries/Esiur/Core/AsyncReply.cs
Normal file
@@ -0,0 +1,432 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Esiur.Resource;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
[AsyncMethodBuilder(typeof(AsyncReplyBuilder))]
|
||||
public class AsyncReply
|
||||
{
|
||||
|
||||
public DateTime ReadyTime;
|
||||
|
||||
protected List<Action<object>> callbacks = new List<Action<object>>();
|
||||
protected object result;
|
||||
|
||||
protected List<Action<AsyncException>> errorCallbacks = null;
|
||||
|
||||
protected List<Action<ProgressType, uint, uint>> progressCallbacks = null;
|
||||
|
||||
protected List<Action<object>> chunkCallbacks = null;
|
||||
|
||||
protected List<Action<object>> propagationCallbacks = null;
|
||||
protected List<Action<byte, string>> warningCallbacks = null;
|
||||
|
||||
|
||||
object asyncLock = new object();
|
||||
|
||||
//public Timer timeout;// = new Timer()
|
||||
protected bool resultReady = false;
|
||||
AsyncException exception;
|
||||
// StackTrace trace;
|
||||
AutoResetEvent mutex = new AutoResetEvent(false);
|
||||
|
||||
public static int MaxId;
|
||||
|
||||
public int Id;
|
||||
|
||||
public bool Ready
|
||||
{
|
||||
get { return resultReady; }
|
||||
}
|
||||
|
||||
public bool Failed => exception != null;
|
||||
|
||||
public Exception Exception => exception;
|
||||
|
||||
public static AsyncReply<T> FromResult<T>(T result) => new AsyncReply<T>(result);
|
||||
|
||||
public object Wait()
|
||||
{
|
||||
if (resultReady)
|
||||
return result;
|
||||
|
||||
mutex.WaitOne();
|
||||
|
||||
if (exception != null)
|
||||
throw exception;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
//int timeoutMilliseconds = 0;
|
||||
public AsyncReply Timeout(int milliseconds, Action callback = null)
|
||||
{
|
||||
|
||||
//timeoutMilliseconds = milliseconds;
|
||||
|
||||
Task.Delay(milliseconds).ContinueWith(x =>
|
||||
{
|
||||
if (!resultReady && exception == null)
|
||||
{
|
||||
TriggerError(new AsyncException(ErrorType.Management,
|
||||
(ushort)ExceptionCode.Timeout, "Execution timeout expired."));
|
||||
|
||||
callback?.Invoke();
|
||||
}
|
||||
});
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public object Wait(int millisecondsTimeout)
|
||||
{
|
||||
if (resultReady)
|
||||
return result;
|
||||
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Wait");
|
||||
|
||||
if (!mutex.WaitOne(millisecondsTimeout))
|
||||
{
|
||||
var e = new Exception("AsyncReply timeout");
|
||||
TriggerError(e);
|
||||
throw e;
|
||||
}
|
||||
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Wait ended");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public object Result
|
||||
{
|
||||
get { return result; }
|
||||
}
|
||||
|
||||
|
||||
protected string codePath, codeMethod;
|
||||
protected int codeLine;
|
||||
|
||||
public AsyncReply Then(Action<object> callback, [CallerMemberName] string methodName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
|
||||
{
|
||||
if (codeLine == 0)
|
||||
{
|
||||
codeLine = lineNumber; codeMethod = methodName; codePath = filePath;
|
||||
}
|
||||
//lock (callbacksLock)
|
||||
//{
|
||||
lock (asyncLock)
|
||||
{
|
||||
// trace = new StackTrace();
|
||||
|
||||
if (resultReady)
|
||||
{
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Then ready");
|
||||
|
||||
callback(result);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//timeout = new Timer(x =>
|
||||
//{
|
||||
// // Get calling method name
|
||||
// Console.WriteLine(trace.GetFrame(1).GetMethod().Name);
|
||||
|
||||
// var tr = String.Join("\r\n", trace.GetFrames().Select(f => f.GetMethod().Name));
|
||||
// timeout.Dispose();
|
||||
|
||||
// tr = trace.ToString();
|
||||
// throw new Exception("Request timeout " + Id);
|
||||
//}, null, 15000, 0);
|
||||
|
||||
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Then pending");
|
||||
|
||||
callbacks.Add(callback);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncReply Error(Action<AsyncException> callback)
|
||||
{
|
||||
|
||||
if (errorCallbacks == null)
|
||||
errorCallbacks = new List<Action<AsyncException>>();
|
||||
|
||||
errorCallbacks.Add(callback);
|
||||
|
||||
if (exception != null)
|
||||
callback(exception);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply Progress(Action<ProgressType, uint, uint> callback)
|
||||
{
|
||||
if (progressCallbacks == null)
|
||||
progressCallbacks = new List<Action<ProgressType, uint, uint>>();
|
||||
|
||||
progressCallbacks.Add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply Warning(Action<byte, string> callback)
|
||||
{
|
||||
if (warningCallbacks == null)
|
||||
warningCallbacks = new List<Action<byte, string>>();
|
||||
|
||||
warningCallbacks.Add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply Chunk(Action<object> callback)
|
||||
{
|
||||
if (chunkCallbacks == null)
|
||||
chunkCallbacks = new List<Action<object>>();
|
||||
|
||||
chunkCallbacks.Add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply Propagation(Action<object> callback)
|
||||
{
|
||||
if (propagationCallbacks == null)
|
||||
propagationCallbacks = new List<Action<object>>();
|
||||
|
||||
propagationCallbacks.Add(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply Trigger(object result)
|
||||
{
|
||||
lock (asyncLock)
|
||||
{
|
||||
ReadyTime = DateTime.Now;
|
||||
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (exception != null)
|
||||
return this;
|
||||
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Trigger");
|
||||
|
||||
if (resultReady)
|
||||
return this;
|
||||
|
||||
this.result = result;
|
||||
|
||||
resultReady = true;
|
||||
|
||||
//if (mutex != null)
|
||||
mutex.Set();
|
||||
|
||||
foreach (var cb in callbacks)
|
||||
cb(result);
|
||||
|
||||
|
||||
//if (Debug)
|
||||
// Console.WriteLine($"AsyncReply: {Id} Trigger ended");
|
||||
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply TriggerError(Exception exception)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (resultReady)
|
||||
return this;
|
||||
|
||||
if (exception is AsyncException)
|
||||
this.exception = exception as AsyncException;
|
||||
else
|
||||
this.exception = new AsyncException(exception);
|
||||
|
||||
if (errorCallbacks != null)
|
||||
{
|
||||
foreach (var cb in errorCallbacks)
|
||||
cb(this.exception);
|
||||
}
|
||||
else
|
||||
{
|
||||
// no error handlers found
|
||||
throw exception;
|
||||
}
|
||||
|
||||
mutex?.Set();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply TriggerProgress(ProgressType type, uint value, uint max)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (progressCallbacks != null)
|
||||
foreach (var cb in progressCallbacks)
|
||||
cb(type, value, max);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply TriggerWarning(byte level, string message)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (warningCallbacks != null)
|
||||
foreach (var cb in warningCallbacks)
|
||||
cb(level, message);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public AsyncReply TriggerPropagation(object value)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (propagationCallbacks != null)
|
||||
foreach (var cb in propagationCallbacks)
|
||||
cb(value);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncReply TriggerChunk(object value)
|
||||
{
|
||||
|
||||
//timeout?.Dispose();
|
||||
|
||||
|
||||
if (chunkCallbacks != null)
|
||||
foreach (var cb in chunkCallbacks)
|
||||
cb(value);
|
||||
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncAwaiter GetAwaiter()
|
||||
{
|
||||
return new AsyncAwaiter(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncReply()
|
||||
{
|
||||
// this.Debug = true;
|
||||
Id = MaxId++;
|
||||
}
|
||||
|
||||
public AsyncReply(object result)
|
||||
{
|
||||
// this.Debug = true;
|
||||
|
||||
ReadyTime = DateTime.Now;
|
||||
|
||||
resultReady = true;
|
||||
this.result = result;
|
||||
|
||||
Id = MaxId++;
|
||||
}
|
||||
|
||||
/*
|
||||
public AsyncReply<T> Then(Action<T> callback)
|
||||
{
|
||||
base.Then(new Action<object>(o => callback((T)o)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Trigger(T result)
|
||||
{
|
||||
Trigger((object)result);
|
||||
}
|
||||
|
||||
public Task<bool> MoveNext(CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public AsyncReply()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public new Task<T> Task
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Task.ContinueWith<T>((t) =>
|
||||
{
|
||||
|
||||
#if NETSTANDARD
|
||||
return (T)t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t);
|
||||
#else
|
||||
return (T)t.GetType().GetProperty("Result").GetValue(t);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public T Current => throw new NotImplementedException();
|
||||
|
||||
public AsyncReply(T result)
|
||||
: base(result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
}
|
||||
68
Libraries/Esiur/Core/AsyncReplyBuilder.cs
Normal file
68
Libraries/Esiur/Core/AsyncReplyBuilder.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Esiur.Misc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncReplyBuilder
|
||||
{
|
||||
AsyncReply reply;
|
||||
|
||||
AsyncReplyBuilder(AsyncReply reply)
|
||||
{
|
||||
this.reply = reply;
|
||||
}
|
||||
|
||||
public static AsyncReplyBuilder Create()
|
||||
{
|
||||
return new AsyncReplyBuilder(new AsyncReply());
|
||||
}
|
||||
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
Global.Log("AsyncReplyBuilder", LogType.Debug, "SetStateMachine");
|
||||
}
|
||||
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
reply.TriggerError(exception);
|
||||
}
|
||||
|
||||
public void SetResult()
|
||||
{
|
||||
reply.Trigger(null);
|
||||
}
|
||||
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
awaiter.OnCompleted(stateMachine.MoveNext);
|
||||
}
|
||||
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
|
||||
}
|
||||
|
||||
public AsyncReply Task
|
||||
{
|
||||
get
|
||||
{
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
68
Libraries/Esiur/Core/AsyncReplyBuilderGeneric.cs
Normal file
68
Libraries/Esiur/Core/AsyncReplyBuilderGeneric.cs
Normal file
@@ -0,0 +1,68 @@
|
||||
using Esiur.Misc;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public class AsyncReplyBuilder<T>
|
||||
{
|
||||
AsyncReply<T> reply;
|
||||
|
||||
AsyncReplyBuilder(AsyncReply<T> reply)
|
||||
{
|
||||
this.reply = reply;
|
||||
}
|
||||
|
||||
public static AsyncReplyBuilder<T> Create()
|
||||
{
|
||||
return new AsyncReplyBuilder<T>(new AsyncReply<T>());
|
||||
}
|
||||
|
||||
public void Start<TStateMachine>(ref TStateMachine stateMachine)
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
stateMachine.MoveNext();
|
||||
}
|
||||
|
||||
public void SetStateMachine(IAsyncStateMachine stateMachine)
|
||||
{
|
||||
Global.Log("AsyncReplyBuilderGeneric", LogType.Debug, "SetStateMachine");
|
||||
}
|
||||
|
||||
public void SetException(Exception exception)
|
||||
{
|
||||
reply.TriggerError(exception);
|
||||
}
|
||||
|
||||
public void SetResult(T result)
|
||||
{
|
||||
reply.Trigger(result);
|
||||
}
|
||||
|
||||
public void AwaitOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : INotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
awaiter.OnCompleted(stateMachine.MoveNext);
|
||||
}
|
||||
|
||||
public void AwaitUnsafeOnCompleted<TAwaiter, TStateMachine>(
|
||||
ref TAwaiter awaiter, ref TStateMachine stateMachine)
|
||||
where TAwaiter : ICriticalNotifyCompletion
|
||||
where TStateMachine : IAsyncStateMachine
|
||||
{
|
||||
awaiter.UnsafeOnCompleted(stateMachine.MoveNext);
|
||||
}
|
||||
|
||||
public AsyncReply<T> Task
|
||||
{
|
||||
get
|
||||
{
|
||||
return reply;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
384
Libraries/Esiur/Core/AsyncReplyGeneric.cs
Normal file
384
Libraries/Esiur/Core/AsyncReplyGeneric.cs
Normal file
@@ -0,0 +1,384 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Esiur.Resource;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
[AsyncMethodBuilder(typeof(AsyncReplyBuilder<>))]
|
||||
public class AsyncReply<T> : AsyncReply
|
||||
{
|
||||
|
||||
public AsyncReply<T> Then(Action<T> callback, [CallerMemberName] string methodName = null, [CallerFilePath] string filePath = null, [CallerLineNumber] int lineNumber = 0)
|
||||
{
|
||||
if (base.codeLine == 0)
|
||||
{
|
||||
base.codeLine = lineNumber; base.codeMethod = methodName; base.codePath = filePath;
|
||||
}
|
||||
|
||||
base.Then((x) => callback((T)x));
|
||||
return this;
|
||||
}
|
||||
|
||||
public new AsyncReply<T> Progress(Action<ProgressType, uint, uint> callback)
|
||||
{
|
||||
base.Progress(callback);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
public AsyncReply<T> Chunk(Action<T> callback)
|
||||
{
|
||||
chunkCallbacks.Add((x) => callback((T)x));
|
||||
return this;
|
||||
}
|
||||
|
||||
public AsyncReply(T result)
|
||||
: base(result)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
public AsyncReply()
|
||||
: base()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public new AsyncAwaiter<T> GetAwaiter()
|
||||
{
|
||||
return new AsyncAwaiter<T>(this);
|
||||
}
|
||||
|
||||
public new T Wait()
|
||||
{
|
||||
return (T)base.Wait();
|
||||
}
|
||||
|
||||
public new T Wait(int millisecondsTimeout)
|
||||
{
|
||||
return (T)base.Wait(millisecondsTimeout);
|
||||
}
|
||||
|
||||
/*
|
||||
protected new List<Action> callbacks = new List<Action>();
|
||||
protected new object result;
|
||||
|
||||
protected new List<Action<AsyncException>> errorCallbacks = new List<Action<AsyncException>>();
|
||||
|
||||
protected new List<Action<ProgressType, int, int>> progressCallbacks = new List<Action<ProgressType, int, int>>();
|
||||
|
||||
protected new List<Action> chunkCallbacks = new List<Action>();
|
||||
|
||||
//List<AsyncAwaiter> awaiters = new List<AsyncAwaiter>();
|
||||
|
||||
object asyncLock = new object();
|
||||
|
||||
//public Timer timeout;// = new Timer()
|
||||
|
||||
AsyncException exception;
|
||||
// StackTrace trace;
|
||||
AutoResetEvent mutex = new AutoResetEvent(false);
|
||||
|
||||
public static int MaxId;
|
||||
|
||||
public int Id;
|
||||
|
||||
public bool Ready
|
||||
{
|
||||
get { return resultReady; }
|
||||
|
||||
}
|
||||
|
||||
|
||||
public T Wait()
|
||||
{
|
||||
|
||||
if (resultReady)
|
||||
return result;
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Wait");
|
||||
|
||||
//mutex = new AutoResetEvent(false);
|
||||
mutex.WaitOne();
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Wait ended");
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
public object Result
|
||||
{
|
||||
get { return result; }
|
||||
}
|
||||
|
||||
|
||||
public IAsyncReply<T> Then(Action<T> callback)
|
||||
{
|
||||
//lock (callbacksLock)
|
||||
//{
|
||||
lock (asyncLock)
|
||||
{
|
||||
// trace = new StackTrace();
|
||||
|
||||
if (resultReady)
|
||||
{
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Then ready");
|
||||
|
||||
callback(result);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
//timeout = new Timer(x =>
|
||||
//{
|
||||
// // Get calling method name
|
||||
// Console.WriteLine(trace.GetFrame(1).GetMethod().Name);
|
||||
|
||||
// var tr = String.Join("\r\n", trace.GetFrames().Select(f => f.GetMethod().Name));
|
||||
// timeout.Dispose();
|
||||
|
||||
// tr = trace.ToString();
|
||||
// throw new Exception("Request timeout " + Id);
|
||||
//}, null, 15000, 0);
|
||||
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Then pending");
|
||||
|
||||
|
||||
|
||||
callbacks.Add(callback);
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public IAsyncReply<T> Error(Action<AsyncException> callback)
|
||||
{
|
||||
// lock (callbacksLock)
|
||||
// {
|
||||
errorCallbacks.Add(callback);
|
||||
|
||||
if (exception != null)
|
||||
callback(exception);
|
||||
|
||||
return this;
|
||||
//}
|
||||
}
|
||||
|
||||
public IAsyncReply<T> Progress(Action<ProgressType, int, int> callback)
|
||||
{
|
||||
//lock (callbacksLock)
|
||||
//{
|
||||
progressCallbacks.Add(callback);
|
||||
return this;
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
public IAsyncReply<T> Chunk(Action<T> callback)
|
||||
{
|
||||
// lock (callbacksLock)
|
||||
// {
|
||||
chunkCallbacks.Add(callback);
|
||||
return this;
|
||||
// }
|
||||
}
|
||||
|
||||
public void Trigger(object result)
|
||||
{
|
||||
lock (asyncLock)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Trigger");
|
||||
|
||||
if (resultReady)
|
||||
return;
|
||||
|
||||
this.result = (T)result;
|
||||
|
||||
resultReady = true;
|
||||
|
||||
//if (mutex != null)
|
||||
mutex.Set();
|
||||
|
||||
foreach (var cb in callbacks)
|
||||
cb((T)result);
|
||||
|
||||
|
||||
if (Debug)
|
||||
Console.WriteLine($"AsyncReply: {Id} Trigger ended");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public void TriggerError(Exception exception)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (resultReady)
|
||||
return;
|
||||
|
||||
if (exception is AsyncException)
|
||||
this.exception = exception as AsyncException;
|
||||
else
|
||||
this.exception = new AsyncException(ErrorType.Management, 0, exception.Message);
|
||||
|
||||
|
||||
// lock (callbacksLock)
|
||||
// {
|
||||
foreach (var cb in errorCallbacks)
|
||||
cb(this.exception);
|
||||
// }
|
||||
|
||||
mutex?.Set();
|
||||
|
||||
}
|
||||
|
||||
public void TriggerProgress(ProgressType type, int value, int max)
|
||||
{
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (resultReady)
|
||||
return;
|
||||
|
||||
//lock (callbacksLock)
|
||||
//{
|
||||
foreach (var cb in progressCallbacks)
|
||||
cb(type, value, max);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
|
||||
public void TriggerChunk(object value)
|
||||
{
|
||||
|
||||
//timeout?.Dispose();
|
||||
|
||||
if (resultReady)
|
||||
return;
|
||||
|
||||
//lock (callbacksLock)
|
||||
//{
|
||||
foreach (var cb in chunkCallbacks)
|
||||
cb((T)value);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
public AsyncAwaiter<T> GetAwaiter()
|
||||
{
|
||||
return new AsyncAwaiter<T>(this);
|
||||
}
|
||||
|
||||
|
||||
|
||||
public AsyncReply()
|
||||
{
|
||||
// this.Debug = true;
|
||||
Id = MaxId++;
|
||||
}
|
||||
|
||||
public AsyncReply(T result)
|
||||
{
|
||||
// this.Debug = true;
|
||||
resultReady = true;
|
||||
this.result = result;
|
||||
|
||||
Id = MaxId++;
|
||||
}
|
||||
|
||||
/*
|
||||
public AsyncReply<T> Then(Action<T> callback)
|
||||
{
|
||||
base.Then(new Action<object>(o => callback((T)o)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void Trigger(T result)
|
||||
{
|
||||
Trigger((object)result);
|
||||
}
|
||||
|
||||
public Task<bool> MoveNext(CancellationToken cancellationToken)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
public AsyncReply()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public new Task<T> Task
|
||||
{
|
||||
get
|
||||
{
|
||||
return base.Task.ContinueWith<T>((t) =>
|
||||
{
|
||||
|
||||
#if NETSTANDARD
|
||||
return (T)t.GetType().GetTypeInfo().GetProperty("Result").GetValue(t);
|
||||
#else
|
||||
return (T)t.GetType().GetProperty("Result").GetValue(t);
|
||||
#endif
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public T Current => throw new NotImplementedException();
|
||||
|
||||
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
12
Libraries/Esiur/Core/ErrorType.cs
Normal file
12
Libraries/Esiur/Core/ErrorType.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public enum ErrorType
|
||||
{
|
||||
Management,
|
||||
Exception,
|
||||
Warning
|
||||
}
|
||||
50
Libraries/Esiur/Core/ExceptionCode.cs
Normal file
50
Libraries/Esiur/Core/ExceptionCode.cs
Normal file
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public enum ExceptionCode : ushort
|
||||
{
|
||||
RuntimeException,
|
||||
HostNotReachable,
|
||||
AccessDenied,
|
||||
UserOrTokenNotFound,
|
||||
ChallengeFailed,
|
||||
ResourceNotFound,
|
||||
AttachDenied,
|
||||
InvalidMethod,
|
||||
InvokeDenied,
|
||||
CreateDenied,
|
||||
AddParentDenied,
|
||||
AddChildDenied,
|
||||
ViewAttributeDenied,
|
||||
UpdateAttributeDenied,
|
||||
StoreNotFound,
|
||||
ParentNotFound,
|
||||
ChildNotFound,
|
||||
ResourceIsNotStore,
|
||||
DeleteDenied,
|
||||
DeleteFailed,
|
||||
UpdateAttributeFailed,
|
||||
GetAttributesFailed,
|
||||
ClearAttributesFailed,
|
||||
TypeDefNotFound,
|
||||
RenameDenied,
|
||||
ClassNotFound,
|
||||
MethodNotFound,
|
||||
PropertyNotFound,
|
||||
SetPropertyDenied,
|
||||
ReadOnlyProperty,
|
||||
GeneralFailure,
|
||||
AddToStoreFailed,
|
||||
NotAttached,
|
||||
AlreadyListened,
|
||||
AlreadyUnsubscribed,
|
||||
NotSubscribable,
|
||||
ParseError,
|
||||
Timeout,
|
||||
NotSupported,
|
||||
NotImplemented,
|
||||
NotAllowed
|
||||
}
|
||||
13
Libraries/Esiur/Core/ExceptionLevel.cs
Normal file
13
Libraries/Esiur/Core/ExceptionLevel.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public enum ExceptionLevel
|
||||
{
|
||||
Code = 0x1,
|
||||
Message = 0x2,
|
||||
Source = 0x4,
|
||||
Trace = 0x8
|
||||
}
|
||||
40
Libraries/Esiur/Core/IDestructible.cs
Normal file
40
Libraries/Esiur/Core/IDestructible.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
#nullable enable
|
||||
|
||||
public delegate void DestroyedEvent(object sender);
|
||||
|
||||
public interface IDestructible
|
||||
{
|
||||
event DestroyedEvent? OnDestroy;
|
||||
void Destroy();
|
||||
}
|
||||
49
Libraries/Esiur/Core/InvocationContext.cs
Normal file
49
Libraries/Esiur/Core/InvocationContext.cs
Normal file
@@ -0,0 +1,49 @@
|
||||
using Esiur.Protocol;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core
|
||||
{
|
||||
public class InvocationContext
|
||||
{
|
||||
private uint CallbackId;
|
||||
|
||||
internal bool Ended;
|
||||
|
||||
public void Chunk(object value)
|
||||
{
|
||||
if (Ended)
|
||||
throw new Exception("Execution has ended.");
|
||||
|
||||
Connection.SendChunk(CallbackId, value);
|
||||
}
|
||||
|
||||
public void Progress(uint value, uint max) {
|
||||
|
||||
if (Ended)
|
||||
throw new Exception("Execution has ended.");
|
||||
|
||||
Connection.SendProgress(CallbackId, value, max);
|
||||
}
|
||||
|
||||
public void Warning(byte level, string message)
|
||||
{
|
||||
|
||||
if (Ended)
|
||||
throw new Exception("Execution has ended.");
|
||||
|
||||
Connection.SendWarning(CallbackId, level, message);
|
||||
}
|
||||
|
||||
public EpConnection Connection { get; internal set; }
|
||||
|
||||
|
||||
internal InvocationContext(EpConnection connection, uint callbackId)
|
||||
{
|
||||
Connection = connection;
|
||||
CallbackId = callbackId;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
39
Libraries/Esiur/Core/LogType.cs
Normal file
39
Libraries/Esiur/Core/LogType.cs
Normal file
@@ -0,0 +1,39 @@
|
||||
|
||||
/*
|
||||
|
||||
Copyright (c) 2017 Ahmed Kh. Zamil
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
*/
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public enum LogType
|
||||
{
|
||||
Debug,
|
||||
Warning,
|
||||
Error,
|
||||
}
|
||||
11
Libraries/Esiur/Core/ProgressType.cs
Normal file
11
Libraries/Esiur/Core/ProgressType.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Esiur.Core;
|
||||
|
||||
public enum ProgressType
|
||||
{
|
||||
Execution,
|
||||
Network,
|
||||
}
|
||||
Reference in New Issue
Block a user