Best Coyote code snippet using Microsoft.Coyote.Actors.ActorExecutionContext.GetNextOperationId
CoyoteRuntime.cs
Source:CoyoteRuntime.cs  
...239        /// Creates a new task operation.240        /// </summary>241        internal TaskOperation CreateTaskOperation(bool isDelay = false)242        {243            ulong operationId = this.GetNextOperationId();244            TaskOperation op;245            if (isDelay)246            {247                op = new TaskDelayOperation(operationId, $"TaskDelay({operationId})", this.Configuration.TimeoutDelay,248                    this.Scheduler);249            }250            else251            {252                op = new TaskOperation(operationId, $"Task({operationId})", this.Scheduler);253            }254            this.Scheduler.RegisterOperation(op);255            return op;256        }257        /// <summary>258        /// Schedules the specified action to be executed asynchronously.259        /// </summary>260#if !DEBUG261        [DebuggerStepThrough]262#endif263        internal Task ScheduleAction(Action action, Task predecessor, OperationExecutionOptions options,264            bool isDelay = false, CancellationToken cancellationToken = default)265        {266            cancellationToken.ThrowIfCancellationRequested();267            TaskOperation op = this.CreateTaskOperation(isDelay);268            var context = new OperationContext<Action, object>(op, action, predecessor, options, cancellationToken);269            var task = new Task(this.ExecuteOperation, context, cancellationToken);270            return this.ScheduleTaskOperation(op, task, context.ResultSource);271        }272        /// <summary>273        /// Schedules the specified function to be executed asynchronously.274        /// </summary>275#if !DEBUG276        [DebuggerStepThrough]277#endif278        internal Task<Task> ScheduleFunction(Func<Task> function, Task predecessor, CancellationToken cancellationToken)279        {280            cancellationToken.ThrowIfCancellationRequested();281            Task<Task> task = null;282            TaskOperation op = this.CreateTaskOperation();283            var context = new AsyncOperationContext<Func<Task>, Task, Task>(op, function, task, predecessor,284                OperationExecutionOptions.None, cancellationToken);285            task = new Task<Task>(this.ExecuteOperation<Func<Task>, Task, Task>, context, cancellationToken);286            return this.ScheduleTaskOperation(op, task, context.ExecutorSource);287        }288        /// <summary>289        /// Schedules the specified function to be executed asynchronously.290        /// </summary>291#if !DEBUG292        [DebuggerStepThrough]293#endif294        internal Task<Task<TResult>> ScheduleFunction<TResult>(Func<Task<TResult>> function, Task predecessor, CancellationToken cancellationToken)295        {296            cancellationToken.ThrowIfCancellationRequested();297            Task<TResult> task = null;298            TaskOperation op = this.CreateTaskOperation();299            var context = new AsyncOperationContext<Func<Task<TResult>>, Task<TResult>, TResult>(op, function, task, predecessor,300                OperationExecutionOptions.None, cancellationToken);301            task = new Task<TResult>(this.ExecuteOperation<Func<Task<TResult>>, Task<TResult>, TResult>, context, cancellationToken);302            return this.ScheduleTaskOperation(op, task, context.ExecutorSource);303        }304        /// <summary>305        /// Schedules the specified function to be executed asynchronously.306        /// </summary>307#if !DEBUG308        [DebuggerStepThrough]309#endif310        internal CoyoteTasks.Task ScheduleAsyncFunction(Func<CoyoteTasks.Task> function, Task predecessor, CancellationToken cancellationToken)311        {312            cancellationToken.ThrowIfCancellationRequested();313            Task<Task> task = null;314            TaskOperation op = this.CreateTaskOperation();315            var context = new AsyncOperationContext<Func<CoyoteTasks.Task>, Task, Task>(op, function, task, predecessor,316                OperationExecutionOptions.None, cancellationToken);317            task = new Task<Task>(this.ExecuteOperation<Func<CoyoteTasks.Task>, Task, Task>, context, cancellationToken);318            return new CoyoteTasks.Task(this, this.ScheduleTaskOperation(op, task, context.ResultSource));319        }320        /// <summary>321        /// Schedules the specified function to be executed asynchronously.322        /// </summary>323#if !DEBUG324        [DebuggerStepThrough]325#endif326        internal CoyoteTasks.Task<TResult> ScheduleAsyncFunction<TResult>(Func<CoyoteTasks.Task<TResult>> function, Task predecessor,327            CancellationToken cancellationToken)328        {329            cancellationToken.ThrowIfCancellationRequested();330            Task<TResult> task = null;331            TaskOperation op = this.CreateTaskOperation();332            var context = new AsyncOperationContext<Func<CoyoteTasks.Task<TResult>>, Task<TResult>, TResult>(op, function, task, predecessor,333                OperationExecutionOptions.None, cancellationToken);334            task = new Task<TResult>(this.ExecuteOperation<Func<CoyoteTasks.Task<TResult>>, Task<TResult>, TResult>, context, cancellationToken);335            return new CoyoteTasks.Task<TResult>(this, this.ScheduleTaskOperation(op, task, context.ResultSource));336        }337        /// <summary>338        /// Schedules the specified function to be executed asynchronously.339        /// </summary>340#if !DEBUG341        [DebuggerStepThrough]342#endif343        internal Task<TResult> ScheduleFunction<TResult>(Func<TResult> function, Task predecessor, CancellationToken cancellationToken)344        {345            cancellationToken.ThrowIfCancellationRequested();346            TaskOperation op = this.CreateTaskOperation();347            var context = new OperationContext<Func<TResult>, TResult>(op, function, predecessor,348                OperationExecutionOptions.None, cancellationToken);349            var task = new Task<TResult>(this.ExecuteOperation<Func<TResult>, TResult, TResult>, context, cancellationToken);350            return this.ScheduleTaskOperation(op, task, context.ResultSource);351        }352        /// <summary>353        /// Schedules the specified task operation for execution.354        /// </summary>355        private Task<TResult> ScheduleTaskOperation<TResult>(TaskOperation op, Task task, TaskCompletionSource<TResult> tcs)356        {357            IO.Debug.WriteLine("<CreateLog> Operation '{0}' was created to execute task '{1}'.", op.Name, task.Id);358            task.Start();359            this.Scheduler.WaitOperationStart(op);360            this.Scheduler.ScheduleNextOperation(AsyncOperationType.Create);361            this.TaskMap.TryAdd(tcs.Task, op);362            return tcs.Task;363        }364        /// <summary>365        /// Execute the operation with the specified context.366        /// </summary>367        internal void ExecuteOperation(object state)368        {369            // Extract the expected operation context from the task state.370            var context = state as OperationContext<Action, object>;371            TaskOperation op = context.Operation;372            CancellationToken ct = context.CancellationToken;373            Exception exception = null;374            try375            {376                // Update the current asynchronous control flow with the current runtime instance,377                // allowing future retrieval in the same asynchronous call stack.378                AssignAsyncControlFlowRuntime(this);379                // Notify the scheduler that the operation started. This will yield execution until380                // the operation is ready to get scheduled.381                this.Scheduler.StartOperation(op);382                if (context.Predecessor != null)383                {384                    // If the predecessor task is asynchronous, then wait until it completes.385                    ct.ThrowIfCancellationRequested();386                    op.TryBlockUntilTaskCompletes(context.Predecessor);387                }388                if (context.Options.HasFlag(OperationExecutionOptions.YieldAtStart))389                {390                    // Try yield execution to the next operation.391                    this.Scheduler.ScheduleNextOperation(AsyncOperationType.Default, true);392                }393                if (op is TaskDelayOperation delayOp)394                {395                    // Try delay scheduling this operation.396                    delayOp.DelayUntilTimeout();397                }398                // Check if the operation must be canceled before starting the work.399                ct.ThrowIfCancellationRequested();400                // Start executing the work.401                context.Work();402            }403            catch (Exception ex)404            {405                if (context.Options.HasFlag(OperationExecutionOptions.FailOnException))406                {407                    this.Assert(false, "Unhandled exception. {0}", ex);408                }409                else410                {411                    // Unwrap and cache the exception to propagate it.412                    exception = UnwrapException(ex);413                    this.ReportThrownException(exception);414                }415            }416            finally417            {418                IO.Debug.WriteLine("<ScheduleDebug> Completed operation '{0}' on task '{1}'.", op.Name, Task.CurrentId);419                op.OnCompleted();420                // Set the result task completion source to notify to the awaiters that the operation421                // has been completed, and schedule the next enabled operation.422                SetTaskCompletionSource(context.ResultSource, null, exception, default);423                this.Scheduler.ScheduleNextOperation(AsyncOperationType.Join);424            }425        }426        /// <summary>427        /// Execute the (asynchronous) operation with the specified context.428        /// </summary>429        private TResult ExecuteOperation<TWork, TExecutor, TResult>(object state)430        {431            // Extract the expected operation context from the task state.432            var context = state as AsyncOperationContext<TWork, TExecutor, TResult> ?? state as OperationContext<TWork, TResult>;433            TaskOperation op = context.Operation;434            CancellationToken ct = context.CancellationToken;435            TResult result = default;436            Exception exception = null;437            // The operation execution logic uses two task completion sources: (1) an executor TCS and (2) a result TCS.438            // We do this to model the execution of tasks in the .NET runtime. For example, the `Task.Factory.StartNew`439            // method has different semantics from `Task.Run`, e.g. the returned task from `Task.Factory.StartNew(Func<T>)`440            // completes at the start of an asynchronous operation, so someone cannot await on it for the completion of441            // the operation. Instead, someone needs to first use `task.Unwrap()`, and then await on the unwrapped task.442            // To model this, the executor TCS completes at the start of the operation, and contains in its `task.AsyncState`443            // a reference to the result TCS. This approach allows us to implement `task.Unwrap` in a way that gives access444            // to the result TCS, which someone can then await for the asynchronous completion of the operation.445            try446            {447                // Update the current asynchronous control flow with the current runtime instance,448                // allowing future retrieval in the same asynchronous call stack.449                AssignAsyncControlFlowRuntime(this);450                // Notify the scheduler that the operation started. This will yield execution until451                // the operation is ready to get scheduled.452                this.Scheduler.StartOperation(op);453                if (context is AsyncOperationContext<TWork, TExecutor, TResult> asyncContext)454                {455                    // If the operation is asynchronous, then set the executor task completion source, which456                    // can be used by `UnwrapTask` to unwrap and return the task executing this operation.457                    SetTaskCompletionSource(asyncContext.ExecutorSource, asyncContext.Executor, null, ct);458                }459                if (context.Predecessor != null)460                {461                    // If the predecessor task is asynchronous, then wait until it completes.462                    ct.ThrowIfCancellationRequested();463                    op.TryBlockUntilTaskCompletes(context.Predecessor);464                }465                // Check if the operation must be canceled before starting the work.466                ct.ThrowIfCancellationRequested();467                // Start executing the (asynchronous) work.468                Task executor = null;469                if (context.Work is Func<Task<TResult>> funcWithTaskResult)470                {471                    executor = funcWithTaskResult();472                }473                else if (context.Work is Func<Task> funcWithTask)474                {475                    executor = funcWithTask();476                }477                else if (context.Work is Func<CoyoteTasks.Task<TResult>> funcWithCoyoteTaskResult)478                {479                    // TODO: temporary until we remove the custom task type.480                    executor = funcWithCoyoteTaskResult().UncontrolledTask;481                }482                else if (context.Work is Func<CoyoteTasks.Task> funcWithCoyoteTask)483                {484                    // TODO: temporary until we remove the custom task type.485                    executor = funcWithCoyoteTask().UncontrolledTask;486                }487                else if (context.Work is Func<TResult> func)488                {489                    result = func();490                }491                else492                {493                    throw new NotSupportedException($"Unable to execute work with unsupported type {context.Work.GetType()}.");494                }495                if (executor != null)496                {497                    // If the work task is asynchronous, then wait until it completes.498                    op.TryBlockUntilTaskCompletes(executor);499                    if (executor.IsFaulted)500                    {501                        // Propagate the failing exception by rethrowing it.502                        ExceptionDispatchInfo.Capture(executor.Exception).Throw();503                    }504                    else if (executor.IsCanceled)505                    {506                        if (op.Exception != null)507                        {508                            // An exception has been already captured, so propagate it.509                            ExceptionDispatchInfo.Capture(op.Exception).Throw();510                        }511                        else512                        {513                            // Wait the canceled executor (which is non-blocking as it has already completed)514                            // to throw the generated `OperationCanceledException`.515                            executor.Wait();516                        }517                    }518                    // Safely get the result without blocking as the work has completed.519                    result = executor is Task<TResult> resultTask ? resultTask.Result :520                        executor is TResult r ? r : default;521                }522            }523            catch (Exception ex)524            {525                // Unwrap and cache the exception to propagate it.526                exception = UnwrapException(ex);527                this.ReportThrownException(exception);528            }529            finally530            {531                IO.Debug.WriteLine("<ScheduleDebug> Completed operation '{0}' on task '{1}'.", op.Name, Task.CurrentId);532                op.OnCompleted();533                // Set the result task completion source to notify to the awaiters that the operation534                // has been completed, and schedule the next enabled operation.535                SetTaskCompletionSource(context.ResultSource, result, exception, default);536                this.Scheduler.ScheduleNextOperation(AsyncOperationType.Join);537            }538            return result;539        }540        /// <summary>541        /// Sets the specified task completion source with a result, cancelation or exception.542        /// </summary>543        private static void SetTaskCompletionSource<TResult>(TaskCompletionSource<TResult> tcs, TResult result,544            Exception ex, CancellationToken cancellationToken)545        {546            if (cancellationToken.IsCancellationRequested)547            {548                tcs.SetCanceled();549            }550            else if (ex != null)551            {552                tcs.SetException(ex);553            }554            else555            {556                tcs.SetResult(result);557            }558        }559        /// <summary>560        /// Schedules the specified delay to be executed asynchronously.561        /// </summary>562#if !DEBUG563        [DebuggerStepThrough]564#endif565        internal Task ScheduleDelay(TimeSpan delay, CancellationToken cancellationToken)566        {567            // TODO: support cancellations during testing.568            if (delay.TotalMilliseconds is 0)569            {570                // If the delay is 0, then complete synchronously.571                return Task.CompletedTask;572            }573            // TODO: cache the dummy delay action to optimize memory.574            var options = OperationContext.CreateOperationExecutionOptions();575            return this.ScheduleAction(() => { }, null, options, true, cancellationToken);576        }577        /// <summary>578        /// Schedules the specified task awaiter continuation to be executed asynchronously.579        /// </summary>580#if !DEBUG581        [DebuggerStepThrough]582#endif583        internal void ScheduleTaskAwaiterContinuation(Task task, Action continuation)584        {585            try586            {587                var callerOp = this.Scheduler?.GetExecutingOperation<TaskOperation>();588                if (callerOp is null)589                {590                    OperationScheduler.ThrowUncontrolledTaskException();591                }592                if (IsCurrentOperationExecutingAsynchronously())593                {594                    IO.Debug.WriteLine("<Task> '{0}' is dispatching continuation of task '{1}'.", callerOp.Name, task.Id);595                    var options = OperationContext.CreateOperationExecutionOptions();596                    this.ScheduleAction(continuation, task, options);597                    IO.Debug.WriteLine("<Task> '{0}' dispatched continuation of task '{1}'.", callerOp.Name, task.Id);598                }599                else600                {601                    IO.Debug.WriteLine("<Task> '{0}' is executing continuation of task '{1}' on task '{2}'.",602                        callerOp.Name, task.Id, Task.CurrentId);603                    continuation();604                    IO.Debug.WriteLine("<Task> '{0}' resumed after continuation of task '{1}' on task '{2}'.",605                        callerOp.Name, task.Id, Task.CurrentId);606                }607            }608            catch (ExecutionCanceledException)609            {610                IO.Debug.WriteLine($"<Exception> ExecutionCanceledException was thrown from task '{Task.CurrentId}'.");611            }612        }613        /// <summary>614        /// Schedules the specified yield awaiter continuation to be executed asynchronously.615        /// </summary>616#if !DEBUG617        [DebuggerStepThrough]618#endif619        internal void ScheduleYieldAwaiterContinuation(Action continuation)620        {621            try622            {623                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();624                IO.Debug.WriteLine("<Task> '{0}' is executing a yield operation.", callerOp.Id);625                var options = OperationContext.CreateOperationExecutionOptions(yieldAtStart: true);626                this.ScheduleAction(continuation, null, options);627            }628            catch (ExecutionCanceledException)629            {630                IO.Debug.WriteLine($"<Exception> ExecutionCanceledException was thrown from task '{Task.CurrentId}'.");631            }632        }633        /// <summary>634        /// Creates a controlled task that will complete when all tasks635        /// in the specified enumerable collection have completed.636        /// </summary>637#if !DEBUG638        [DebuggerStepThrough]639#endif640        internal Task WhenAllTasksCompleteAsync(Task[] tasks)641        {642            if (tasks is null)643            {644                throw new ArgumentNullException(nameof(tasks));645            }646            else if (tasks.Length is 0)647            {648                return Task.CompletedTask;649            }650            return this.ScheduleAction(() =>651            {652                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();653                callerOp.BlockUntilTasksComplete(tasks, waitAll: true);654                List<Exception> exceptions = null;655                foreach (var task in tasks)656                {657                    if (task.IsFaulted)658                    {659                        exceptions ??= new List<Exception>();660                        exceptions.Add(task.Exception is AggregateException aex ? aex.InnerException : task.Exception);661                    }662                }663                if (exceptions != null)664                {665                    throw new AggregateException(exceptions);666                }667            }, null, OperationContext.CreateOperationExecutionOptions());668        }669        /// <summary>670        /// Creates a controlled task that will complete when all tasks671        /// in the specified enumerable collection have completed.672        /// </summary>673#if !DEBUG674        [DebuggerStepThrough]675#endif676        internal Task WhenAllTasksCompleteAsync(CoyoteTasks.Task[] tasks)677        {678            if (tasks is null)679            {680                throw new ArgumentNullException(nameof(tasks));681            }682            else if (tasks.Length is 0)683            {684                return Task.CompletedTask;685            }686            return this.ScheduleAction(() =>687            {688                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();689                callerOp.BlockUntilTasksComplete(tasks, waitAll: true);690                List<Exception> exceptions = null;691                foreach (var task in tasks)692                {693                    if (task.IsFaulted)694                    {695                        exceptions ??= new List<Exception>();696                        exceptions.Add(task.Exception is AggregateException aex ? aex.InnerException : task.Exception);697                    }698                }699                if (exceptions != null)700                {701                    throw new AggregateException(exceptions);702                }703            }, null, OperationContext.CreateOperationExecutionOptions());704        }705        /// <summary>706        /// Creates a controlled task that will complete when all tasks707        /// in the specified enumerable collection have completed.708        /// </summary>709#if !DEBUG710        [DebuggerStepThrough]711#endif712        internal Task<TResult[]> WhenAllTasksCompleteAsync<TResult>(Task<TResult>[] tasks)713        {714            if (tasks is null)715            {716                throw new ArgumentNullException(nameof(tasks));717            }718            else if (tasks.Length is 0)719            {720                return Task.FromResult(Array.Empty<TResult>());721            }722            return this.ScheduleFunction(() =>723            {724                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();725                callerOp.BlockUntilTasksComplete(tasks, waitAll: true);726                List<Exception> exceptions = null;727                foreach (var task in tasks)728                {729                    if (task.IsFaulted)730                    {731                        exceptions ??= new List<Exception>();732                        exceptions.Add(task.Exception is AggregateException aex ? aex.InnerException : task.Exception);733                    }734                }735                if (exceptions != null)736                {737                    throw new AggregateException(exceptions);738                }739                int idx = 0;740                TResult[] result = new TResult[tasks.Length];741                foreach (var task in tasks)742                {743                    result[idx] = task.Result;744                    idx++;745                }746                return result;747            }, null, default);748        }749        /// <summary>750        /// Creates a controlled task that will complete when all tasks751        /// in the specified enumerable collection have completed.752        /// </summary>753#if !DEBUG754        [DebuggerStepThrough]755#endif756        internal Task<TResult[]> WhenAllTasksCompleteAsync<TResult>(CoyoteTasks.Task<TResult>[] tasks)757        {758            if (tasks is null)759            {760                throw new ArgumentNullException(nameof(tasks));761            }762            else if (tasks.Length is 0)763            {764                return Task.FromResult(Array.Empty<TResult>());765            }766            return this.ScheduleFunction(() =>767            {768                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();769                callerOp.BlockUntilTasksComplete(tasks, waitAll: true);770                List<Exception> exceptions = null;771                foreach (var task in tasks)772                {773                    if (task.IsFaulted)774                    {775                        exceptions ??= new List<Exception>();776                        exceptions.Add(task.Exception is AggregateException aex ? aex.InnerException : task.Exception);777                    }778                }779                if (exceptions != null)780                {781                    throw new AggregateException(exceptions);782                }783                int idx = 0;784                TResult[] result = new TResult[tasks.Length];785                foreach (var task in tasks)786                {787                    result[idx] = task.Result;788                    idx++;789                }790                return result;791            }, null, default);792        }793        /// <summary>794        /// Creates a controlled task that will complete when any task795        /// in the specified enumerable collection have completed.796        /// </summary>797#if !DEBUG798        [DebuggerStepThrough]799#endif800        internal Task<Task> WhenAnyTaskCompletesAsync(Task[] tasks)801        {802            if (tasks is null)803            {804                throw new ArgumentNullException(nameof(tasks));805            }806            else if (tasks.Length is 0)807            {808                throw new ArgumentException("The tasks argument contains no tasks.");809            }810            var task = this.ScheduleFunction(() =>811            {812                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();813                callerOp.BlockUntilTasksComplete(tasks, waitAll: false);814                Task result = null;815                foreach (var task in tasks)816                {817                    if (task.IsCompleted)818                    {819                        result = task;820                        break;821                    }822                }823                return Task.FromResult(result);824            }, null, default);825            return this.UnwrapTask(task);826        }827        /// <summary>828        /// Creates a controlled task that will complete when any task829        /// in the specified enumerable collection have completed.830        /// </summary>831#if !DEBUG832        [DebuggerStepThrough]833#endif834        internal CoyoteTasks.Task<CoyoteTasks.Task> WhenAnyTaskCompletesAsync(CoyoteTasks.Task[] tasks)835        {836            if (tasks is null)837            {838                throw new ArgumentNullException(nameof(tasks));839            }840            else if (tasks.Length is 0)841            {842                throw new ArgumentException("The tasks argument contains no tasks.");843            }844            return this.ScheduleAsyncFunction(() =>845            {846                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();847                callerOp.BlockUntilTasksComplete(tasks, waitAll: false);848                CoyoteTasks.Task result = null;849                foreach (var task in tasks)850                {851                    if (task.IsCompleted)852                    {853                        result = task;854                        break;855                    }856                }857                return CoyoteTasks.Task.FromResult(result);858            }, null, default);859        }860        /// <summary>861        /// Creates a controlled task that will complete when any task862        /// in the specified enumerable collection have completed.863        /// </summary>864#if !DEBUG865        [DebuggerStepThrough]866#endif867        internal Task<Task<TResult>> WhenAnyTaskCompletesAsync<TResult>(Task<TResult>[] tasks)868        {869            if (tasks is null)870            {871                throw new ArgumentNullException(nameof(tasks));872            }873            else if (tasks.Length is 0)874            {875                throw new ArgumentException("The tasks argument contains no tasks.");876            }877            var task = this.ScheduleFunction(() =>878            {879                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();880                callerOp.BlockUntilTasksComplete(tasks, waitAll: false);881                Task<TResult> result = null;882                foreach (var task in tasks)883                {884                    if (task.IsCompleted)885                    {886                        result = task;887                        break;888                    }889                }890                return Task.FromResult(result);891            }, null, default);892            return this.UnwrapTask(task);893        }894        /// <summary>895        /// Creates a controlled task that will complete when any task896        /// in the specified enumerable collection have completed.897        /// </summary>898#if !DEBUG899        [DebuggerStepThrough]900#endif901        internal CoyoteTasks.Task<CoyoteTasks.Task<TResult>> WhenAnyTaskCompletesAsync<TResult>(CoyoteTasks.Task<TResult>[] tasks)902        {903            if (tasks is null)904            {905                throw new ArgumentNullException(nameof(tasks));906            }907            else if (tasks.Length is 0)908            {909                throw new ArgumentException("The tasks argument contains no tasks.");910            }911            return this.ScheduleAsyncFunction(() =>912            {913                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();914                callerOp.BlockUntilTasksComplete(tasks, waitAll: false);915                CoyoteTasks.Task<TResult> result = null;916                foreach (var task in tasks)917                {918                    if (task.IsCompleted)919                    {920                        result = task;921                        break;922                    }923                }924                return CoyoteTasks.Task.FromResult(result);925            }, null, default);926        }927        /// <summary>928        /// Waits for all of the provided controlled task objects to complete execution within929        /// a specified number of milliseconds or until a cancellation token is cancelled.930        /// </summary>931        internal bool WaitAllTasksComplete(Task[] tasks)932        {933            // TODO: support cancellations during testing.934            if (tasks is null)935            {936                throw new ArgumentNullException(nameof(tasks));937            }938            else if (tasks.Length is 0)939            {940                return true;941            }942            var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();943            callerOp.BlockUntilTasksComplete(tasks, waitAll: true);944            // TODO: support timeouts during testing, this would become false if there is a timeout.945            return true;946        }947        /// <summary>948        /// Waits for all of the provided controlled task objects to complete execution within949        /// a specified number of milliseconds or until a cancellation token is cancelled.950        /// </summary>951        internal bool WaitAllTasksComplete(CoyoteTasks.Task[] tasks)952        {953            // TODO: support cancellations during testing.954            if (tasks is null)955            {956                throw new ArgumentNullException(nameof(tasks));957            }958            else if (tasks.Length is 0)959            {960                return true;961            }962            var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();963            callerOp.BlockUntilTasksComplete(tasks, waitAll: true);964            // TODO: support timeouts during testing, this would become false if there is a timeout.965            return true;966        }967        /// <summary>968        /// Waits for any of the provided controlled task objects to complete execution within969        /// a specified number of milliseconds or until a cancellation token is cancelled.970        /// </summary>971#if !DEBUG972        [DebuggerStepThrough]973#endif974        internal int WaitAnyTaskCompletes(Task[] tasks)975        {976            // TODO: support cancellations during testing.977            if (tasks is null)978            {979                throw new ArgumentNullException(nameof(tasks));980            }981            else if (tasks.Length is 0)982            {983                throw new ArgumentException("The tasks argument contains no tasks.");984            }985            var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();986            callerOp.BlockUntilTasksComplete(tasks, waitAll: false);987            int result = -1;988            for (int i = 0; i < tasks.Length; i++)989            {990                if (tasks[i].IsCompleted)991                {992                    result = i;993                    break;994                }995            }996            // TODO: support timeouts during testing, this would become false if there is a timeout.997            return result;998        }999        /// <summary>1000        /// Waits for any of the provided controlled task objects to complete execution within1001        /// a specified number of milliseconds or until a cancellation token is cancelled.1002        /// </summary>1003#if !DEBUG1004        [DebuggerStepThrough]1005#endif1006        internal int WaitAnyTaskCompletes(CoyoteTasks.Task[] tasks)1007        {1008            // TODO: support cancellations during testing.1009            if (tasks is null)1010            {1011                throw new ArgumentNullException(nameof(tasks));1012            }1013            else if (tasks.Length is 0)1014            {1015                throw new ArgumentException("The tasks argument contains no tasks.");1016            }1017            var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();1018            callerOp.BlockUntilTasksComplete(tasks, waitAll: false);1019            int result = -1;1020            for (int i = 0; i < tasks.Length; i++)1021            {1022                if (tasks[i].IsCompleted)1023                {1024                    result = i;1025                    break;1026                }1027            }1028            // TODO: support timeouts during testing, this would become false if there is a timeout.1029            return result;1030        }1031        /// <summary>1032        /// Waits for the task to complete execution. The wait terminates if a timeout interval1033        /// elapses or a cancellation token is canceled before the task completes.1034        /// </summary>1035        internal bool WaitTaskCompletes(Task task)1036        {1037            this.AssertIsAwaitedTaskControlled(task);1038            // TODO: support timeouts and cancellation tokens.1039            if (!task.IsCompleted)1040            {1041                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();1042                callerOp.BlockUntilTaskCompletes(task);1043            }1044            if (task.IsFaulted)1045            {1046                // Propagate the failing exception by rethrowing it.1047                ExceptionDispatchInfo.Capture(task.Exception).Throw();1048            }1049            return true;1050        }1051        /// <summary>1052        /// Waits for the task to complete execution and returns the result.1053        /// </summary>1054        internal TResult WaitTaskCompletes<TResult>(Task<TResult> task)1055        {1056            this.AssertIsAwaitedTaskControlled(task);1057            // TODO: support timeouts and cancellation tokens.1058            if (!task.IsCompleted)1059            {1060                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();1061                callerOp.BlockUntilTaskCompletes(task);1062            }1063            if (task.IsFaulted)1064            {1065                // Propagate the failing exception by rethrowing it.1066                ExceptionDispatchInfo.Capture(task.Exception).Throw();1067            }1068            return task.Result;1069        }1070        /// <summary>1071        /// Unwraps the specified task.1072        /// </summary>1073        internal Task UnwrapTask(Task<Task> task)1074        {1075            var unwrappedTask = task.AsyncState is TaskCompletionSource<Task> tcs ? tcs.Task : task.Unwrap();1076            this.TaskMap.TryGetValue(task, out TaskOperation op);1077            this.TaskMap.TryAdd(unwrappedTask, op);1078            return unwrappedTask;1079        }1080        /// <summary>1081        /// Unwraps the specified task.1082        /// </summary>1083        internal Task<TResult> UnwrapTask<TResult>(Task<Task<TResult>> task)1084        {1085            var unwrappedTask = task.AsyncState is TaskCompletionSource<TResult> tcs ? tcs.Task : task.Unwrap();1086            this.TaskMap.TryGetValue(task, out TaskOperation op);1087            this.TaskMap.TryAdd(unwrappedTask, op);1088            return unwrappedTask;1089        }1090        /// <summary>1091        /// Callback invoked when the task of a task completion source is accessed.1092        /// </summary>1093        internal void OnTaskCompletionSourceGetTask(Task task)1094        {1095            this.TaskMap.TryAdd(task, null);1096        }1097        /// <summary>1098        /// Callback invoked when the <see cref="AsyncTaskMethodBuilder.SetException"/> is accessed.1099        /// </summary>1100        internal void OnAsyncTaskMethodBuilderSetException(Exception exception)1101        {1102            var op = this.Scheduler.GetExecutingOperation<TaskOperation>();1103            op?.SetException(exception);1104        }1105        /// <summary>1106        /// Checks if the currently executing operation is controlled by the runtime.1107        /// </summary>1108#if !DEBUG1109        [DebuggerHidden]1110#endif1111        internal void CheckExecutingOperationIsControlled() =>1112            this.Scheduler.GetExecutingOperation<AsyncOperation>();1113        /// <summary>1114        /// Callback invoked when the <see cref="CoyoteTasks.YieldAwaitable.YieldAwaiter.GetResult"/> is called.1115        /// </summary>1116#if !DEBUG1117        [DebuggerStepThrough]1118#endif1119        internal void OnYieldAwaiterGetResult() => this.Scheduler.ScheduleNextOperation(AsyncOperationType.Yield);1120        /// <summary>1121        /// Callback invoked when the executing operation is waiting for the specified task to complete.1122        /// </summary>1123#if !DEBUG1124        [DebuggerStepThrough]1125#endif1126        internal void OnWaitTask(Task task)1127        {1128            if (!task.IsCompleted)1129            {1130                var callerOp = this.Scheduler.GetExecutingOperation<TaskOperation>();1131                callerOp.BlockUntilTaskCompletes(task);1132            }1133        }1134        /// <summary>1135        /// Returns true if the current operation is executing an asynchronous state machine, else false.1136        /// </summary>1137        private static bool IsCurrentOperationExecutingAsynchronously()1138        {1139            StackTrace st = new StackTrace(false);1140            bool result = false;1141            for (int i = 0; i < st.FrameCount; i++)1142            {1143                // Traverse the stack trace to find if the current operation is executing an asynchronous state machine.1144                MethodBase method = st.GetFrame(i).GetMethod();1145                if (method.DeclaringType == typeof(AsyncVoidMethodBuilder) &&1146                    (method.Name is "AwaitOnCompleted" || method.Name is "AwaitUnsafeOnCompleted"))1147                {1148                    // The operation is executing the root of an async void method, so we need to inline.1149                    break;1150                }1151                else if (method.Name is "MoveNext" &&1152                    method.DeclaringType.Namespace != typeof(OperationScheduler).Namespace &&1153                    typeof(IAsyncStateMachine).IsAssignableFrom(method.DeclaringType))1154                {1155                    // The operation is executing the `MoveNext` of an asynchronous state machine.1156                    result = true;1157                    break;1158                }1159            }1160            return result;1161        }1162        /// <summary>1163        /// Processes an unhandled exception in the specified asynchronous operation.1164        /// </summary>1165        private void ProcessUnhandledExceptionInOperation(AsyncOperation op, Exception ex)1166        {1167            string message = null;1168            Exception exception = UnwrapException(ex);1169            if (exception is ExecutionCanceledException ece)1170            {1171                IO.Debug.WriteLine("<Exception> {0} was thrown from operation '{1}'.",1172                    ece.GetType().Name, op.Name);1173                if (this.Scheduler.IsAttached)1174                {1175                    // TODO: add some tests for this, so that we check that a task (or lock) that1176                    // was cached and reused from prior iteration indeed cannot cause the runtime1177                    // to hang anymore.1178                    message = string.Format(CultureInfo.InvariantCulture, $"Unhandled exception. {ece}");1179                }1180            }1181            else if (exception is TaskSchedulerException)1182            {1183                IO.Debug.WriteLine("<Exception> {0} was thrown from operation '{1}'.",1184                    exception.GetType().Name, op.Name);1185            }1186            else if (exception is ObjectDisposedException)1187            {1188                IO.Debug.WriteLine("<Exception> {0} was thrown from operation '{1}' with reason '{2}'.",1189                    exception.GetType().Name, op.Name, ex.Message);1190            }1191            else1192            {1193                message = string.Format(CultureInfo.InvariantCulture, $"Unhandled exception. {exception}");1194            }1195            if (message != null)1196            {1197                // Report the unhandled exception.1198                this.Scheduler.NotifyUnhandledException(exception, message);1199            }1200        }1201        /// <summary>1202        /// Unwraps the specified exception.1203        /// </summary>1204        private static Exception UnwrapException(Exception ex)1205        {1206            Exception exception = ex;1207            while (exception is TargetInvocationException)1208            {1209                exception = exception.InnerException;1210            }1211            if (exception is AggregateException)1212            {1213                exception = exception.InnerException;1214            }1215            return exception;1216        }1217        /// <summary>1218        /// Registers a new specification monitor of the specified <see cref="Type"/>.1219        /// </summary>1220        internal void RegisterMonitor<T>()1221            where T : Monitor => this.DefaultActorExecutionContext.RegisterMonitor<T>();1222        /// <summary>1223        /// Invokes the specified monitor with the specified <see cref="Event"/>.1224        /// </summary>1225        internal void Monitor<T>(Event e)1226            where T : Monitor => this.DefaultActorExecutionContext.Monitor<T>(e);1227        /// <summary>1228        /// Checks if the assertion holds, and if not, throws an <see cref="AssertionFailureException"/> exception.1229        /// </summary>1230        internal void Assert(bool predicate) => this.SpecificationEngine.Assert(predicate);1231        /// <summary>1232        /// Checks if the assertion holds, and if not, throws an <see cref="AssertionFailureException"/> exception.1233        /// </summary>1234        internal void Assert(bool predicate, string s, object arg0) => this.SpecificationEngine.Assert(predicate, s, arg0);1235        /// <summary>1236        /// Checks if the assertion holds, and if not, throws an <see cref="AssertionFailureException"/> exception.1237        /// </summary>1238        internal void Assert(bool predicate, string s, object arg0, object arg1) =>1239            this.SpecificationEngine.Assert(predicate, s, arg0, arg1);1240        /// <summary>1241        /// Checks if the assertion holds, and if not, throws an <see cref="AssertionFailureException"/> exception.1242        /// </summary>1243        internal void Assert(bool predicate, string s, object arg0, object arg1, object arg2) =>1244            this.SpecificationEngine.Assert(predicate, s, arg0, arg1, arg2);1245        /// <summary>1246        /// Checks if the assertion holds, and if not, throws an <see cref="AssertionFailureException"/> exception.1247        /// </summary>1248        internal void Assert(bool predicate, string s, params object[] args) => this.SpecificationEngine.Assert(predicate, s, args);1249        /// <summary>1250        /// Creates a liveness monitor that checks if the specified task eventually completes execution successfully.1251        /// </summary>1252#if !DEBUG1253        [DebuggerStepThrough]1254#endif1255        internal void MonitorTaskCompletion(Task task) => this.SpecificationEngine.MonitorTaskCompletion(task);1256#if !DEBUG1257        [DebuggerStepThrough]1258#endif1259        internal void AssertIsAwaitedTaskControlled(Task task)1260        {1261            if (!task.IsCompleted && !this.TaskMap.ContainsKey(task) &&1262                !this.Configuration.IsPartiallyControlledTestingEnabled)1263            {1264                this.Assert(false, $"Awaiting uncontrolled task with id '{task.Id}' is not allowed: " +1265                    "either mock the method that created the task, or rewrite the method's assembly.");1266            }1267        }1268#if !DEBUG1269        [DebuggerStepThrough]1270#endif1271        internal void AssertIsReturnedTaskControlled(Task task, string methodName)1272        {1273            if (!task.IsCompleted && !this.TaskMap.ContainsKey(task) &&1274                !this.Configuration.IsPartiallyControlledTestingEnabled)1275            {1276                this.Assert(false, $"Method '{methodName}' returned an uncontrolled task with id '{task.Id}', " +1277                    "which is not allowed: either mock the method, or rewrite the method's assembly.");1278            }1279        }1280        /// <summary>1281        /// Returns a controlled nondeterministic boolean choice.1282        /// </summary>1283        internal bool GetNondeterministicBooleanChoice(int maxValue, string callerName, string callerType) =>1284            this.DefaultActorExecutionContext.GetNondeterministicBooleanChoice(maxValue, callerName, callerType);1285        /// <summary>1286        /// Returns a controlled nondeterministic integer choice.1287        /// </summary>1288        internal int GetNondeterministicIntegerChoice(int maxValue, string callerName, string callerType) =>1289            this.DefaultActorExecutionContext.GetNondeterministicIntegerChoice(maxValue, callerName, callerType);1290        /// <summary>1291        /// Returns the next available unique operation id.1292        /// </summary>1293        /// <returns>Value representing the next available unique operation id.</returns>1294        internal ulong GetNextOperationId() =>1295            // Atomically increments and safely wraps the value into an unsigned long.1296            (ulong)Interlocked.Increment(ref this.OperationIdCounter) - 1;1297        /// <summary>1298        /// Gets the <see cref="AsyncOperation"/> that is executing on the current1299        /// synchronization context, or null if no such operation is executing.1300        /// </summary>1301        internal TAsyncOperation GetExecutingOperation<TAsyncOperation>()1302            where TAsyncOperation : AsyncOperation =>1303            this.Scheduler.GetExecutingOperation<TAsyncOperation>();1304        /// <summary>1305        /// Schedules the next controlled asynchronous operation. This method1306        /// is only used during testing.1307        /// </summary>1308        internal void ScheduleNextOperation(AsyncOperationType type = AsyncOperationType.Default, bool isYielding = false, int[] hashArray = null)...ActorExecutionContext.cs
Source:ActorExecutionContext.cs  
...116            this.ValueGenerator = valueGenerator;117            this.LogWriter = logWriter;118        }119        /// <inheritdoc/>120        public ActorId CreateActorId(Type type, string name = null) => new ActorId(type, this.GetNextOperationId(), name, this);121        /// <inheritdoc/>122        public virtual ActorId CreateActorIdFromName(Type type, string name) => new ActorId(type, 0, name, this, true);123        /// <inheritdoc/>124        public virtual ActorId CreateActor(Type type, Event initialEvent = null, EventGroup eventGroup = null) =>125            this.CreateActor(null, type, null, initialEvent, null, eventGroup);126        /// <inheritdoc/>127        public virtual ActorId CreateActor(Type type, string name, Event initialEvent = null, EventGroup eventGroup = null) =>128            this.CreateActor(null, type, name, initialEvent, null, eventGroup);129        /// <inheritdoc/>130        public virtual ActorId CreateActor(ActorId id, Type type, Event initialEvent = null, EventGroup eventGroup = null) =>131            this.CreateActor(id, type, null, initialEvent, null, eventGroup);132        /// <inheritdoc/>133        public virtual Task<ActorId> CreateActorAndExecuteAsync(Type type, Event initialEvent = null, EventGroup eventGroup = null) =>134            this.CreateActorAndExecuteAsync(null, type, null, initialEvent, null, eventGroup);135        /// <inheritdoc/>136        public virtual Task<ActorId> CreateActorAndExecuteAsync(Type type, string name, Event initialEvent = null, EventGroup eventGroup = null) =>137            this.CreateActorAndExecuteAsync(null, type, name, initialEvent, null, eventGroup);138        /// <inheritdoc/>139        public virtual Task<ActorId> CreateActorAndExecuteAsync(ActorId id, Type type, Event initialEvent = null, EventGroup eventGroup = null) =>140            this.CreateActorAndExecuteAsync(id, type, null, initialEvent, null, eventGroup);141        /// <summary>142        /// Creates a new <see cref="Actor"/> of the specified <see cref="Type"/>.143        /// </summary>144        internal virtual ActorId CreateActor(ActorId id, Type type, string name, Event initialEvent, Actor creator, EventGroup eventGroup)145        {146            Actor actor = this.CreateActor(id, type, name, creator, eventGroup);147            if (actor is StateMachine)148            {149                this.LogWriter.LogCreateStateMachine(actor.Id, creator?.Id.Name, creator?.Id.Type);150            }151            else152            {153                this.LogWriter.LogCreateActor(actor.Id, creator?.Id.Name, creator?.Id.Type);154            }155            this.RunActorEventHandler(actor, initialEvent, true);156            return actor.Id;157        }158        /// <summary>159        /// Creates a new <see cref="Actor"/> of the specified <see cref="Type"/>. The method160        /// returns only when the actor is initialized and the <see cref="Event"/> (if any)161        /// is handled.162        /// </summary>163        internal virtual async Task<ActorId> CreateActorAndExecuteAsync(ActorId id, Type type, string name, Event initialEvent,164            Actor creator, EventGroup eventGroup)165        {166            Actor actor = this.CreateActor(id, type, name, creator, eventGroup);167            if (actor is StateMachine)168            {169                this.LogWriter.LogCreateStateMachine(actor.Id, creator?.Id.Name, creator?.Id.Type);170            }171            else172            {173                this.LogWriter.LogCreateActor(actor.Id, creator?.Id.Name, creator?.Id.Type);174            }175            await this.RunActorEventHandlerAsync(actor, initialEvent, true);176            return actor.Id;177        }178        /// <summary>179        /// Creates a new <see cref="Actor"/> of the specified <see cref="Type"/>.180        /// </summary>181        internal virtual Actor CreateActor(ActorId id, Type type, string name, Actor creator, EventGroup eventGroup)182        {183            if (!type.IsSubclassOf(typeof(Actor)))184            {185                this.Assert(false, "Type '{0}' is not an actor.", type.FullName);186            }187            if (id is null)188            {189                id = this.CreateActorId(type, name);190            }191            else if (id.Runtime != null && id.Runtime != this)192            {193                this.Assert(false, "Unbound actor id '{0}' was created by another runtime.", id.Value);194            }195            else if (id.Type != type.FullName)196            {197                this.Assert(false, "Cannot bind actor id '{0}' of type '{1}' to an actor of type '{2}'.",198                    id.Value, id.Type, type.FullName);199            }200            else201            {202                id.Bind(this);203            }204            // If no event group is provided then inherit the current group from the creator.205            if (eventGroup is null && creator != null)206            {207                eventGroup = creator.EventGroup;208            }209            Actor actor = ActorFactory.Create(type);210            IEventQueue eventQueue = new EventQueue(actor);211            actor.Configure(this, id, null, eventQueue, eventGroup);212            actor.SetupEventHandlers();213            if (!this.ActorMap.TryAdd(id, actor))214            {215                this.Assert(false, $"An actor with id '{id.Value}' was already created by another runtime instance.");216            }217            return actor;218        }219        /// <inheritdoc/>220        public virtual void SendEvent(ActorId targetId, Event initialEvent, EventGroup eventGroup = default, SendOptions options = null) =>221            this.SendEvent(targetId, initialEvent, null, eventGroup, options);222        /// <inheritdoc/>223        public virtual Task<bool> SendEventAndExecuteAsync(ActorId targetId, Event initialEvent,224            EventGroup eventGroup = null, SendOptions options = null) =>225            this.SendEventAndExecuteAsync(targetId, initialEvent, null, eventGroup, options);226        /// <summary>227        /// Sends an asynchronous <see cref="Event"/> to an actor.228        /// </summary>229        internal virtual void SendEvent(ActorId targetId, Event e, Actor sender, EventGroup eventGroup, SendOptions options)230        {231            EnqueueStatus enqueueStatus = this.EnqueueEvent(targetId, e, sender, eventGroup, out Actor target);232            if (enqueueStatus is EnqueueStatus.EventHandlerNotRunning)233            {234                this.RunActorEventHandler(target, null, false);235            }236        }237        /// <summary>238        /// Sends an asynchronous <see cref="Event"/> to an actor. Returns immediately if the target was239        /// already running. Otherwise blocks until the target handles the event and reaches quiescense.240        /// </summary>241        internal virtual async Task<bool> SendEventAndExecuteAsync(ActorId targetId, Event e, Actor sender,242            EventGroup eventGroup, SendOptions options)243        {244            EnqueueStatus enqueueStatus = this.EnqueueEvent(targetId, e, sender, eventGroup, out Actor target);245            if (enqueueStatus is EnqueueStatus.EventHandlerNotRunning)246            {247                await this.RunActorEventHandlerAsync(target, null, false);248                return true;249            }250            return enqueueStatus is EnqueueStatus.Dropped;251        }252        /// <summary>253        /// Enqueues an event to the actor with the specified id.254        /// </summary>255        private EnqueueStatus EnqueueEvent(ActorId targetId, Event e, Actor sender, EventGroup eventGroup, out Actor target)256        {257            if (e is null)258            {259                string message = sender != null ?260                    string.Format("{0} is sending a null event.", sender.Id.ToString()) :261                    "Cannot send a null event.";262                this.Assert(false, message);263            }264            if (targetId is null)265            {266                string message = (sender != null) ?267                    string.Format("{0} is sending event {1} to a null actor.", sender.Id.ToString(), e.ToString())268                    : string.Format("Cannot send event {0} to a null actor.", e.ToString());269                this.Assert(false, message);270            }271            target = this.GetActorWithId<Actor>(targetId);272            // If no group is provided we default to passing along the group from the sender.273            if (eventGroup is null && sender != null)274            {275                eventGroup = sender.EventGroup;276            }277            Guid opId = eventGroup is null ? Guid.Empty : eventGroup.Id;278            if (target is null || target.IsHalted)279            {280                this.LogWriter.LogSendEvent(targetId, sender?.Id.Name, sender?.Id.Type,281                    (sender as StateMachine)?.CurrentStateName ?? default, e, opId, isTargetHalted: true);282                this.HandleDroppedEvent(e, targetId);283                return EnqueueStatus.Dropped;284            }285            this.LogWriter.LogSendEvent(targetId, sender?.Id.Name, sender?.Id.Type,286                (sender as StateMachine)?.CurrentStateName ?? default, e, opId, isTargetHalted: false);287            EnqueueStatus enqueueStatus = target.Enqueue(e, eventGroup, null);288            if (enqueueStatus == EnqueueStatus.Dropped)289            {290                this.HandleDroppedEvent(e, targetId);291            }292            return enqueueStatus;293        }294        /// <summary>295        /// Runs a new asynchronous actor event handler.296        /// This is a fire and forget invocation.297        /// </summary>298        private void RunActorEventHandler(Actor actor, Event initialEvent, bool isFresh)299        {300            Task.Run(async () =>301            {302                try303                {304                    if (isFresh)305                    {306                        await actor.InitializeAsync(initialEvent);307                    }308                    await actor.RunEventHandlerAsync();309                }310                catch (Exception ex)311                {312                    this.Scheduler.IsProgramExecuting = false;313                    this.RaiseOnFailureEvent(ex);314                }315                finally316                {317                    if (actor.IsHalted)318                    {319                        this.ActorMap.TryRemove(actor.Id, out Actor _);320                    }321                }322            });323        }324        /// <summary>325        /// Runs a new asynchronous actor event handler.326        /// </summary>327        private async Task RunActorEventHandlerAsync(Actor actor, Event initialEvent, bool isFresh)328        {329            try330            {331                if (isFresh)332                {333                    await actor.InitializeAsync(initialEvent);334                }335                await actor.RunEventHandlerAsync();336            }337            catch (Exception ex)338            {339                this.Scheduler.IsProgramExecuting = false;340                this.RaiseOnFailureEvent(ex);341                return;342            }343        }344        /// <summary>345        /// Creates a new timer that sends a <see cref="TimerElapsedEvent"/> to its owner actor.346        /// </summary>347        internal virtual IActorTimer CreateActorTimer(TimerInfo info, Actor owner) => new ActorTimer(info, owner);348        /// <inheritdoc/>349        public virtual EventGroup GetCurrentEventGroup(ActorId currentActorId)350        {351            Actor actor = this.GetActorWithId<Actor>(currentActorId);352            return actor?.CurrentEventGroup;353        }354        /// <summary>355        /// Gets the actor of type <typeparamref name="TActor"/> with the specified id,356        /// or null if no such actor exists.357        /// </summary>358        internal TActor GetActorWithId<TActor>(ActorId id)359            where TActor : Actor =>360            id != null && this.ActorMap.TryGetValue(id, out Actor value) &&361            value is TActor actor ? actor : null;362        /// <summary>363        /// Returns the next available unique operation id.364        /// </summary>365        /// <returns>Value representing the next available unique operation id.</returns>366        internal ulong GetNextOperationId() => this.Runtime.GetNextOperationId();367        /// <inheritdoc/>368        public bool RandomBoolean() => this.GetNondeterministicBooleanChoice(2, null, null);369        /// <inheritdoc/>370        public bool RandomBoolean(int maxValue) => this.GetNondeterministicBooleanChoice(maxValue, null, null);371        /// <summary>372        /// Returns a controlled nondeterministic boolean choice.373        /// </summary>374        internal virtual bool GetNondeterministicBooleanChoice(int maxValue, string callerName, string callerType)375        {376            bool result = false;377            if (this.ValueGenerator.Next(maxValue) is 0)378            {379                result = true;380            }...GetNextOperationId
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using Microsoft.Coyote.Actors;4using Microsoft.Coyote.Runtime;5{6    {7        static async Task Main(string[] args)8        {9            var config = Configuration.Create();10            config.MaxSchedulingSteps = 1000000;11            config.MaxFairSchedulingSteps = 1000000;GetNextOperationId
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using Microsoft.Coyote.Actors;4using Microsoft.Coyote.Specifications;5using Microsoft.Coyote.SystematicTesting;6using Microsoft.Coyote.Tasks;7{8    {9        static void Main(string[] args)10        {11            using (var runtime = RuntimeFactory.Create())12            {13                var configuration = Configuration.Create();14                configuration.SchedulingIterations = 1000;15                configuration.SchedulingStrategy = SchedulingStrategy.Random;16                configuration.TestingIterations = 1000;17                configuration.Verbose = 2;18                configuration.ReportActivityCoverage = true;19                configuration.ReportFairScheduling = true;20                configuration.ReportOperationCoverage = true;21                configuration.ReportStateGraph = true;22                configuration.ReportStateGraphEdgeCoverage = true;23                configuration.ReportStateGraphEdgeCoverageThreshold = 0.5;24                configuration.ReportStateGraphMaxUnvisitedStates = 100;25                configuration.ReportStateGraphMaxUnvisitedTransitionsPerState = 100;26                configuration.ReportStateGraphStateCoverage = true;27                configuration.ReportStateGraphStateCoverageThreshold = 0.5;28                configuration.ReportStateGraphTransitionCoverage = true;29                configuration.ReportStateGraphTransitionCoverageThreshold = 0.5;30                configuration.ReportStateGraphUnvisitedStateLimit = 100;31                configuration.ReportStateGraphUnvisitedTransitionLimit = 100;32                configuration.ReportUnhandledExceptions = true;33                configuration.ReportUnhandledExceptionsAsFailures = true;34                configuration.ReportUnprovenLivenessProperties = true;35                configuration.ReportUnprovenSafetyProperties = true;36                configuration.ReportUnprovenSafetyPropertiesAsFailures = true;37                configuration.ReportUnprovenLivenessPropertiesAsFailures = true;38                configuration.ReportUnprovenSafetyPropertiesAsFailures = true;39                configuration.ReportUnprovenLivenessPropertiesAsFailures = true;40                configuration.ReportActivityCoverage = true;41                configuration.ReportFairScheduling = true;42                configuration.ReportOperationCoverage = true;43                configuration.ReportStateGraph = true;44                configuration.ReportStateGraphEdgeCoverage = true;45                configuration.ReportStateGraphEdgeCoverageThreshold = 0.5;46                configuration.ReportStateGraphMaxUnvisitedStates = 100;47                configuration.ReportStateGraphMaxUnvisitedTransitionsPerState = 100;48                configuration.ReportStateGraphStateCoverage = true;GetNextOperationId
Using AI Code Generation
1using System;2using Microsoft.Coyote.Actors;3using Microsoft.Coyote.Actors.Timers;4{5    {6        public static void Main(string[] args)7        {8            var configuration = Configuration.Create();9            var runtime = RuntimeFactory.Create(configuration);10            runtime.CreateActor(typeof(Actor1));11            runtime.Wait();12        }13    }14    {15        private TimerInfo timer;16        protected override void OnInitialize(Event initialEvent)17        {18            this.timer = this.RegisterTimer(this.Id, new E(), 1000, true);19        }20        protected override void OnEvent(Event e)21        {22            this.SendEvent(this.Id, new E());23        }24        protected override void OnTimerElapsed(TimerInfo info)25        {26            if (info == this.timer)27            {28                Console.WriteLine("Timer elapsed");29                var nextOpId = this.GetNextOperationId();30                this.SendEvent(this.Id, new E(), nextOpId);31            }32        }33    }34    {35    }36}37Severity Code Description Project File Line Suppression State Error CS0535 'Program': cannot override inherited member 'Actor.OnEvent(Event)' because it is not marked virtual, abstract, or override CoyoteTest C:\Users\user\source\repos\CoyoteTest\Program.cs 14 Active38Severity Code Description Project File Line Suppression State Error CS0534 'Program' does not implement inherited abstract member 'Actor.OnEvent(Event)' CoyoteTest C:\Users\user\source\repos\CoyoteTest\Program.cs 14 ActiveGetNextOperationId
Using AI Code Generation
1using Microsoft.Coyote.Actors;2using Microsoft.Coyote.Actors.Timers;3using System;4using System.Collections.Generic;5using System.Linq;6using System.Text;7using System.Threading.Tasks;8{9    {10        static void Main(string[] args)11        {12            Console.WriteLine(id);13            Console.ReadLine();14        }15    }16}GetNextOperationId
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using Microsoft.Coyote;4using Microsoft.Coyote.Actors;5using Microsoft.Coyote.Specifications;6using Microsoft.Coyote.Tasks;7{8    [OnEventGotoState(typeof(Start), typeof(State1))]9    [OnEventGotoState(typeof(Event1), typeof(State2))]10    [OnEventGotoState(typeof(Event2), typeof(State1))]11    {12        [OnEntry(nameof(EntryAction1))]13        [OnEventDoAction(typeof(Event1), nameof(Action1))]14        {15        }16        [OnEntry(nameof(EntryAction2))]17        [OnEventDoAction(typeof(Event2), nameof(Action2))]18        {19        }20        void EntryAction1()21        {22            this.SendEvent(this.Id, new Event1());23        }24        void EntryAction2()25        {26            this.SendEvent(this.Id, new Event2());27        }28        void Action1()29        {30        }31        void Action2()32        {33        }34    }35    {36    }37    {38    }39    {40        static void Main(string[] args)41        {42            Runtime runtime = RuntimeFactory.Create();43            runtime.RegisterMonitor(typeof(Actor1));44            runtime.CreateActor(typeof(Actor1));45            runtime.Wait();46        }47    }48}GetNextOperationId
Using AI Code Generation
1using System;2using System.Collections.Generic;3using System.Linq;4using System.Text;5using System.Threading.Tasks;6using Microsoft.Coyote.Actors;7using Microsoft.Coyote.Actors.Timers;8{9    {10        static void Main(string[] args)11        {12            ActorId actorId = ActorId.CreateRandom();13            ActorRuntime runtime = new ActorRuntime();14            int operationId = runtime.GetNextOperationId(actorId);GetNextOperationId
Using AI Code Generation
1using System;2using System.Threading.Tasks;3using Microsoft.Coyote;4using Microsoft.Coyote.Actors;5using Microsoft.Coyote.Runtime;6using Microsoft.Coyote.Tasks;7using Microsoft.Coyote.TestingServices;8using Microsoft.Coyote.TestingServices.Runtime;9using Microsoft.Coyote.TestingServices.SchedulingStrategies;10using Microsoft.Coyote.TestingServices.Tracing.Schedule;11using Microsoft.Coyote.TestingServices.Tracing.Schedule.Default;12using Microsoft.Coyote.TestingServices.Tracing.Schedule.Default.Strategies;13{14    {15        protected override async Task OnInitializeAsync(Event initialEvent)16        {17            var context = this.Runtime.GetActorExecutionContext(this.Id);18            var nextOperationId = context.GetNextOperationId();19            Console.WriteLine("Next operation id of the actor: {0}", nextOperationId);20        }21    }22    {23        public static async Task Main(string[] args)24        {25            var runtime = RuntimeFactory.Create();26            var actor = runtime.CreateActor(typeof(MyActor));27            await runtime.StartAsync();28            await runtime.WaitAsync();29        }30    }31}32using System;33using System.Threading.Tasks;34using Microsoft.Coyote;35using Microsoft.Coyote.Actors;36using Microsoft.Coyote.Runtime;37using Microsoft.Coyote.Tasks;38using Microsoft.Coyote.TestingServices;39using Microsoft.Coyote.TestingServices.Runtime;40using Microsoft.Coyote.TestingServices.SchedulingStrategies;41using Microsoft.Coyote.TestingServices.Tracing.Schedule;42using Microsoft.Coyote.TestingServices.Tracing.Schedule.Default;43using Microsoft.Coyote.TestingServices.Tracing.Schedule.Default.Strategies;44{GetNextOperationId
Using AI Code Generation
1using Microsoft.Coyote;2using Microsoft.Coyote.Actors;3{4    {5        protected override async Task OnInitializeAsync(Event e)6        {7            var id = this.Runtime.GetNextOperationId();8        }9    }10}11using Microsoft.Coyote;12using Microsoft.Coyote.Actors;13{14    {15        protected override async Task OnInitializeAsync(Event e)16        {17            var id = this.Runtime.GetNextOperationId();18        }19    }20}21using Microsoft.Coyote;22using Microsoft.Coyote.Actors;23{24    {25        protected override async Task OnInitializeAsync(Event e)26        {27            var id = this.Runtime.GetNextOperationId();28        }29    }30}31using Microsoft.Coyote;32using Microsoft.Coyote.Actors;33{34    {35        protected override async Task OnInitializeAsync(Event e)36        {37            var id = this.Runtime.GetNextOperationId();38        }39    }40}41using Microsoft.Coyote;42using Microsoft.Coyote.Actors;43{44    {45        protected override async Task OnInitializeAsync(Event e)46        {47            var id = this.Runtime.GetNextOperationId();48        }49    }50}Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
