private async Task _RunJob()

in SimpleDUTClientLibrary/RpcClient.cs [731:798]


        private async Task<string> _RunJob(string command, string args = null,
                                    int pollingInterval = 60,
                                    int timeout = 0,
                                    int pollingDelay = 60,
                                    CancellationToken? cancellationToken = null,
                                    bool returnExObject = false)
        {
            Timer pollingTimer = null;
            Timer timeoutTimer = null;
            TaskCompletionSource<bool> taskCompletionSource = new TaskCompletionSource<bool>();
            Action<int> completionCallback = (x) => taskCompletionSource.TrySetResult(true);

            var jobid = StartJobWithNotification(command, args, completionCallback);

            if (pollingInterval > 0)
            {
                // we need to setup polling
                TimerCallback pollingAction = (o) =>
                {
                    try
                    {
                        if (CheckJobCompletion(jobid))
                        {
                            pollingTimer.Change(Timeout.Infinite, Timeout.Infinite);
                            taskCompletionSource.TrySetResult(true);
                        }
                    }
                    catch (Exception e)
                    {
                        taskCompletionSource.TrySetException(e);
                    }
                };

                pollingTimer = new Timer(pollingAction, null, pollingInterval * 1000, pollingDelay * 1000);
            }
            if (timeout > 0)
            {
                timeoutTimer = new Timer((o) => { taskCompletionSource.SetException(new TimeoutException("RunWithResult timed out.")); }, null, timeout * 1000, Timeout.Infinite);
            }

            var tsk = taskCompletionSource.Task;
            var token = cancellationToken ?? CancellationToken.None;
            token.Register(() => taskCompletionSource.TrySetCanceled());

            try
            {
                // prevents deadlock if someone calls RunJob on a UI thread. 
                await tsk.ConfigureAwait(continueOnCapturedContext: false);
            }
            catch (OperationCanceledException e)
            {
                StopJob(jobid);
                // don't throw until we clean up the timers. 
            }

            pollingTimer?.Dispose();
            timeoutTimer?.Dispose();

            // if we were canceled, throw cancelation exception here
            token.ThrowIfCancellationRequested();

            if (taskCompletionSource.Task.IsFaulted)
            {
                throw taskCompletionSource.Task.Exception;
            }

            return (returnExObject) ? GetJobResultEx(jobid) : GetJobResult(jobid);
        }