public IOJob <TState, TContext, TUserContext, TResult> StartJob <TState, TContext, TUserContext, TResult>(TState state, TContext context, TUserContext userContext, Func <TState, TContext, TUserContext, Task <TResult> > func)
            where TState : class
            where TContext : class
            where TUserContext : class
            where TResult : class
        {
            var jobCtx = new HiddenContext
            {
                Component   = this,
                State       = state,
                Context     = context,
                UserContext = userContext
            };

            jobCtx.JobWrapper = async ctx =>
            {
                try
                {
                    var f = Unsafe.As <Func <object, object, object, Task <object> > >(func);
                    ctx.Result = await f(ctx.State, ctx.Context, ctx.UserContext);
                }
                catch (Exception ex)
                {
                    ctx.Exception = ex;
                }

                lock (ctx.Component.m_ActiveJobs)
                    ctx.Component.m_ActiveJobs.Remove(jobCtx);

                ctx.Component.m_CompletedJobs.Enqueue(jobCtx);
                ctx.Component.m_Synchronizer.Set();
            };

            lock (m_ActiveJobs)
                m_ActiveJobs.Add(Unsafe.As <HiddenContext>(jobCtx));

            Action <object> action = async ctx =>
            {
                var jobCtx = (HiddenContext)ctx;
                await jobCtx.JobWrapper(jobCtx);
            };

            m_TaskFactory.StartNew(action, jobCtx);

            return(new IOJob <TState, TContext, TUserContext, TResult>(jobCtx));
        }
 internal IOJob(object ctx)
 {
     m_Ctx = (HiddenContext)ctx;
 }