예제 #1
0
        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());
        }
예제 #2
0
파일: RdCall.cs 프로젝트: LongJohnCoder/rd
        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);
        }
예제 #3
0
        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);
        }