Mercurial > pub > ImplabNet
diff Implab/Components/RunnableComponent.cs @ 256:c52691faaf21 v3
Removed obsolete App, ComponentContainer
Extracted IAsyncComponent interface
Working on RunnableComponent
author | cin |
---|---|
date | Wed, 11 Apr 2018 03:05:14 +0300 |
parents | 6f4630d0bcd9 |
children | 440801d88019 |
line wrap: on
line diff
--- a/Implab/Components/RunnableComponent.cs Wed Apr 04 15:38:48 2018 +0300 +++ b/Implab/Components/RunnableComponent.cs Wed Apr 11 03:05:14 2018 +0300 @@ -12,7 +12,7 @@ /// This class provides a basic lifecycle from the creation to the /// termination of the component. /// </remarks> - public class RunnableComponent : IRunnable, IInitializable, IDisposable { + public class RunnableComponent : IAsyncComponent, IRunnable, IInitializable, IDisposable { /// <summary> /// This class bounds <see cref="CancellationTokenSource"/> lifetime to the task, @@ -80,7 +80,7 @@ } // this lock is used to synchronize state flow of the component during - // completions or the operations. + // processing calls from a client and internal processes. readonly object m_lock = new object(); // current operation cookie, used to check wheather a call to @@ -88,6 +88,7 @@ // operation, if cookies didn't match ignore completion result. object m_cookie; + // AsyncOperationDscriptor aggregates a task and it's cancellation token AsyncOperationDescriptor m_current = AsyncOperationDescriptor.None; ExecutionState m_state; @@ -152,6 +153,8 @@ var cookie = new object(); if (MoveInitialize(cookie)) ScheduleTask(InitializeInternalAsync, CancellationToken.None, cookie); + else + throw new InvalidOperationException(); } /// <summary> @@ -171,6 +174,8 @@ var cookie = new object(); if (MoveStart(cookie)) ScheduleTask(StartInternalAsync, ct, cookie); + else + throw new InvalidOperationException(); } protected virtual Task StartInternalAsync(CancellationToken ct) { @@ -181,6 +186,8 @@ var cookie = new object(); if (MoveStop(cookie)) ScheduleTask(StopAsync, ct, cookie); + else + throw new InvalidOperationException(); } async Task StopAsync(CancellationToken ct) { @@ -196,6 +203,16 @@ return Task.CompletedTask; } + protected void Fail(Exception err) { + lock(m_lock) { + if (m_state != ExecutionState.Running) + return; + m_cookie = new object(); + LastError = err; + State = ExecutionState.Failed; + } + } + #region state management @@ -256,16 +273,16 @@ } } - + void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { - protected async void ScheduleTask(Func<CancellationToken, Task> next, CancellationToken ct, object cookie) { - try { - m_current = AsyncOperationDescriptor.Create(next, ct); - await m_current.Task; - MoveSuccess(cookie); - } catch (Exception e) { - MoveFailed(e, cookie); - } + m_current = AsyncOperationDescriptor.Create(async (x) => { + try { + await next(x); + MoveSuccess(cookie); + } catch (Exception e) { + MoveFailed(e, cookie); + } + }, ct); } #endregion