public Task <ExitUnityResult> ExitUnityAsync(Lifetime lifetime, bool force) { var lifetimeDef = Lifetime.DefineIntersection(myLifetime, lifetime); if (myBackendUnityHost.BackendUnityModel.Value == null) // no connection { return(Task.FromResult(force ? KillProcess() : new ExitUnityResult(false, "No connection to Unity Editor.", null))); } var protocolTaskSource = new TaskCompletionSource <bool>(); mySolution.Locks.Tasks.StartNew(lifetimeDef.Lifetime, Scheduling.MainGuard, () => myBackendUnityHost.BackendUnityModel.Value.ExitUnity.Start(lifetimeDef.Lifetime, Unit.Instance) .AsTask()); var protocolTask = protocolTaskSource.Task; var waitTask = Task.WhenAny(protocolTask, Task.Delay(TimeSpan.FromSeconds(0.5), lifetimeDef.Lifetime)); // continue on timeout return(waitTask.ContinueWith(t => { lifetimeDef.Terminate(); if (protocolTask.Status != TaskStatus.RanToCompletion && force) { return WaitModelUpdate(); } return Task.FromResult(new ExitUnityResult(false, "Attempt to close Unity Editor failed.", null)); }, TaskContinuationOptions.AttachedToParent).Unwrap()); }
private IRdTask <TRes> StartInternal(Lifetime requestLifetime, TReq request, [NotNull] IScheduler scheduler) { AssertBound(); if (!Async) { AssertThreading(); } AssertNullability(request); var taskId = Proto.Identities.Next(RdId.Nil); var def = Lifetime.DefineIntersection(requestLifetime, myBindLifetime); var task = new WiredRdTask <TReq, TRes>(def, this, taskId, scheduler); Wire.Send(RdId, (writer) => { if (LogSend.IsTraceEnabled()) { LogSend.Trace("call `{0}`::({1}) send request '{2}' : {3}", Location, RdId, taskId, request.PrintToString()); } taskId.Write(writer); WriteRequestDelegate(SerializationContext, writer, request); }); return(task); }
public Task <int> WaitConnectedUnityProcessId(Lifetime lifetime) { var source = new TaskCompletionSource <int>(); var lifetimeDef = Lifetime.DefineIntersection(myLifetime, lifetime); lifetimeDef.SynchronizeWith(source); myBackendUnityHost.BackendUnityModel.ViewNotNull( lifetimeDef.Lifetime, (lt, backendUnityModel) => { backendUnityModel.UnityApplicationData.AdviseNotNull(lt, data => { // We will always get a process ID from the Unity model if (data.UnityProcessId.HasValue) { source.TrySetResult(data.UnityProcessId.Value); } else { source.TrySetException(new InvalidDataException( "UnityApplicationData from Unity does not contain process ID")); } }); }); // ToDo Replace timeout with CancellationToken Task.Delay(ourUnityConnectionTimeout, lifetimeDef.Lifetime).ContinueWith(_ => { if (source.Task.Status != TaskStatus.RanToCompletion) { source.TrySetException(new TimeoutException(ourUnityTimeoutMessage)); } }, lifetimeDef.Lifetime); return(source.Task); }