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