private void RefreshAndRunTask()

in resharper/resharper-unity/src/Unity.Rider/Integration/Core/Feature/UnitTesting/RunViaUnityEditorStrategy.cs [160:255]


        private void RefreshAndRunTask(IUnitTestRun run, TaskCompletionSource<bool> tcs, Lifetime taskLifetime)
        {
            var cancellationTs = run.GetData(ourCancellationTokenSourceKey).NotNull();
            var cancellationToken = cancellationTs.Token;

            myLogger.Trace("Before calling Refresh.");
            Refresh(run.Lifetime, tcs, cancellationToken).ContinueWith(_ =>
            {
                if (tcs.Task.IsCanceled || tcs.Task.IsFaulted) // Refresh failed or was stopped
                    return;

                myLogger.Trace("Refresh. OnCompleted.");

                // KS: Can't use run.Lifetime for ExecuteOrQueueEx here and in all similar places: run.Lifetime is terminated when
                // Unit Test Session is closed from UI without cancelling the run. This will leave task completion source in running state forever.
                mySolution.Locks.ExecuteOrQueueEx(myLifetime, "Check compilation", () =>
                {
                    if (!run.Lifetime.IsAlive || cancellationTs.IsCancellationRequested)
                    {
                        tcs.TrySetCanceled();
                        return;
                    }

                    var backendUnityModel = myBackendUnityHost.BackendUnityModel.Value;
                    if (backendUnityModel == null)
                    {
                        tcs.SetException(new Exception("Unity Editor connection unavailable."));
                        return;
                    }

                    var filters = GetFilters(run);

                    UnitTestLaunchClientControllerInfo? unityClientControllerInfo = null;
                    var clientControllerInfo = run.HostController.GetClientControllerInfo(run);
                    if (clientControllerInfo != null)
                    {
                        unityClientControllerInfo = new UnitTestLaunchClientControllerInfo(
                            clientControllerInfo.AssemblyLocation,
                            clientControllerInfo.ExtraDependencies?.ToList(),
                            clientControllerInfo.TypeName);
                    }

                    var preference = mySolution.GetProtocolSolution().GetFrontendBackendModel().UnitTestPreference.Value;
                    if (preference == null)
                        return;

                    // If we select Both, then start with Edit mode tests
                    var mode = preference == UnitTestLaunchPreference.PlayMode ? TestMode.Play : TestMode.Edit;
                    var launch = new UnitTestLaunch(run.Launch.Session.Id, filters, mode, unityClientControllerInfo);

                    // Set up the launch and subscribe to results. Called immediately, because we know the model isn't
                    // null. Also called when the appdomain is reloaded for play mode tests. The lifetime will correctly
                    // unsubscribe when the appdomain is unloaded
                    myBackendUnityHost.BackendUnityModel!.ViewNotNull<BackendUnityModel>(taskLifetime, (lt, model) =>
                    {
                        myLogger.Trace("UnitTestLaunch.SetValue.");

                        model.UnitTestLaunch.SetValue(launch);
                        SubscribeResults(run, lt, launch);

                        if (preference == UnitTestLaunchPreference.Both)
                        {
                            launch.RunResult.Advise(lt, result =>
                            {
                                if (launch.TestMode == TestMode.Play)
                                    tcs.SetResult(result.Passed);
                                else
                                {
                                    // Now run Play mode
                                    launch = new UnitTestLaunch(launch.SessionId, launch.TestFilters, TestMode.Play,
                                        launch.ClientControllerInfo);
                                    model.UnitTestLaunch.SetValue(launch);
                                    SubscribeResults(run, lt, launch);
                                    launch.RunResult.Advise(lt, result => { tcs.SetResult(result.Passed); });
                                    StartTests(model, run, tcs, lt);
                                }
                            });
                        }
                        else
                        {
                            launch.RunResult.Advise(lt, result => { tcs.SetResult(result.Passed); });
                        }
                    });

                    StartTests(backendUnityModel, run, tcs, taskLifetime);

                    // set results for explicit tests
                    foreach (var element in run.Elements.OfType<INUnitTestElement>().Where(a =>
                        a.RunState == RunState.Explicit && !run.Launch.Criterion.Explicit.Contains(a.Id)))
                    {
                        myUnitTestResultManager.TestFinishing(element, run.Launch.Session,
                            UnitTestStatus.Ignored, "Test should be run explicitly");
                    }
                });
            }, cancellationToken);
        }