コード例 #1
0
        /// <summary>Creates a new outgoing response frame with an OK reply status and a return value.</summary>
        /// <param name="current">The Current object for the corresponding incoming request.</param>
        /// <param name="format">The format type used to marshal classes and exceptions, when this parameter is null
        /// the communicator's default format is used.</param>
        /// <param name="value">The return value to marshal.</param>
        /// <param name="writer">A delegate that must write the value to the frame.</param>
        /// <returns>A new OutgoingResponseFrame.</returns>
        public static OutgoingResponseFrame WithReturnValue <T>(Current current,
                                                                FormatType?format,
                                                                T value,
                                                                OutputStreamWriter <T> writer)
        {
            var response = new OutgoingResponseFrame(current.Encoding);

            byte[] buffer = new byte[256];
            buffer[0] = (byte)ReplyStatus.OK;
            response.Data.Add(buffer);
            var ostr = new OutputStream(Ice1Definitions.Encoding, response.Data, new OutputStream.Position(0, 1),
                                        response.Encoding, format ?? current.Adapter.Communicator.DefaultFormat);

            writer(ostr, value);
            ostr.Save();
            response.Finish();
            return(response);
        }
コード例 #2
0
        private async Task <OutgoingResponseFrame> DispatchAsync(
            OutgoingRequestFrame outgoingRequest,
            int requestId,
            CancellationToken cancel)
        {
            // Increase the direct count to prevent the object adapter from being destroyed while the dispatch is in
            // progress. This will also throw if the object adapter has been deactivated.
            _adapter.IncDirectCount();

            IDispatchObserver?dispatchObserver = null;

            try
            {
                var incomingRequest = new IncomingRequestFrame(outgoingRequest, _adapter.IncomingFrameSizeMax);
                var current         = new Current(_adapter, incomingRequest, oneway: requestId == 0, cancel);

                // Then notify and set dispatch observer, if any.
                ICommunicatorObserver?communicatorObserver = _adapter.Communicator.Observer;
                if (communicatorObserver != null)
                {
                    dispatchObserver = communicatorObserver.GetDispatchObserver(current,
                                                                                requestId,
                                                                                incomingRequest.Size);
                    dispatchObserver?.Attach();
                }

                OutgoingResponseFrame?outgoingResponseFrame = null;
                try
                {
                    IObject?servant = current.Adapter.Find(current.Identity, current.Facet);

                    if (servant == null)
                    {
                        throw new ObjectNotExistException(current.Identity, current.Facet, current.Operation);
                    }

                    ValueTask <OutgoingResponseFrame> vt = servant.DispatchAsync(incomingRequest, current);
                    if (requestId != 0)
                    {
                        // We don't use the cancelable WaitAsync for the await here. The asynchronous dispatch is
                        // not completed yet and we want to make sure the observer is detached only when the dispatch
                        // completes, not when the caller cancels the request.
                        outgoingResponseFrame = await vt.ConfigureAwait(false);

                        outgoingResponseFrame.Finish();
                        dispatchObserver?.Reply(outgoingResponseFrame.Size);
                    }
                }
                catch (Exception ex)
                {
                    RemoteException actualEx;
                    if (ex is RemoteException remoteEx && !remoteEx.ConvertToUnhandled)
                    {
                        actualEx = remoteEx;
                    }
                    else
                    {
                        actualEx = new UnhandledException(current.Identity, current.Facet, current.Operation, ex);
                    }

                    Incoming.ReportException(actualEx, dispatchObserver, current);

                    if (requestId != 0)
                    {
                        outgoingResponseFrame = new OutgoingResponseFrame(incomingRequest, actualEx);
                        outgoingResponseFrame.Finish();
                        dispatchObserver?.Reply(outgoingResponseFrame.Size);
                    }
                }