Esempio n. 1
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        actionWithDirectStream(stream, mergedCancellation.Token);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, cancellationToken))
                    {
                        // important to use cancelationToken here rather than mergedCancellationToken.
                        // there is a slight delay when merged cancellation token will be notified once cancellation token
                        // is raised, it can cause one to be in cancelled mode and the other is not. here, one we
                        // actually care is the cancellation token given in, not the merged cancellation token.
                        cancellationToken.ThrowIfCancellationRequested();
                        throw;
                    }
                }
        }
Esempio n. 2
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task> funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
            }
            catch (OperationCanceledException)
            {
                // if cancelled due to us, throw cancellation exception.
                cancellationToken.ThrowIfCancellationRequested();

                // if canclled due to invocation is failed, rethrow merged cancellation
                throw;
            }
        }
Esempio n. 3
0
        public static async Task InvokeAsync(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Action <Stream, CancellationToken> actionWithDirectStream, CancellationToken cancellationToken)
        {
            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request by adding direct stream name to end of arguments
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        actionWithDirectStream(stream, mergedCancellation.Token);

                        // wait task to finish
                        await task.ConfigureAwait(false);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, mergedCancellation.Token))
                    {
                        cancellationToken.ThrowIfCancellationRequested();
                        throw;
                    }
                }
        }
Esempio n. 4
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request to asset source
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
            }
            catch (Exception ex) when(IsCancelled(ex))
            {
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
        }
Esempio n. 5
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IEnumerable <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            try
            {
                using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                    using (var stream = new ServerDirectStream())
                    {
                        // send request to asset source
                        var task = rpc.InvokeAsync(targetName, arguments.Concat(stream.Name).ToArray());

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
            }
            catch (ObjectDisposedException)
            {
                // object disposed exception can be thrown from StreamJsonRpc if JsonRpc is disposed in the middle of read/write.
                // the way we added cancellation support to the JsonRpc which doesn't support cancellation natively
                // can cause this exception to happen. newer version supports cancellation token natively, but
                // we can't use it now, so we will catch object disposed exception and check cancellation token
                cancellationToken.ThrowIfCancellationRequested();
                throw;
            }
            catch (OperationCanceledException)
            {
                // if cancelled due to us, throw cancellation exception.
                cancellationToken.ThrowIfCancellationRequested();

                // if canclled due to invocation is failed, rethrow merged cancellation
                throw;
            }
        }
Esempio n. 6
0
        public static async Task <T> InvokeAsync <T>(
            this JsonRpc rpc, string targetName, IReadOnlyList <object> arguments,
            Func <Stream, CancellationToken, Task <T> > funcWithDirectStreamAsync, CancellationToken cancellationToken)
        {
            Task task = null;

            using (var mergedCancellation = CancellationTokenSource.CreateLinkedTokenSource(cancellationToken))
                using (var stream = new ServerDirectStream())
                {
                    try
                    {
                        // send request to asset source
                        task = rpc.InvokeWithCancellationAsync(targetName, arguments.Concat(stream.Name).ToArray(), cancellationToken);

                        // if invoke throws an exception, make sure we raise cancellation.
                        RaiseCancellationIfInvokeFailed(task, mergedCancellation, cancellationToken);

                        // wait for asset source to respond
                        await stream.WaitForDirectConnectionAsync(mergedCancellation.Token).ConfigureAwait(false);

                        // run user task with direct stream
                        var result = await funcWithDirectStreamAsync(stream, mergedCancellation.Token).ConfigureAwait(false);

                        // wait task to finish
                        await task.ConfigureAwait(false);

                        return(result);
                    }
                    catch (Exception ex) when(ReportUnlessCanceled(ex, mergedCancellation.Token, cancellationToken))
                    {
                        // important to use cancelationToken here rather than mergedCancellationToken.
                        // there is a slight delay when merged cancellation token will be notified once cancellation token
                        // is raised, it can cause one to be in cancelled mode and the other is not. here, one we
                        // actually care is the cancellation token given in, not the merged cancellation token.
                        cancellationToken.ThrowIfCancellationRequested();

                        // record reason why task got aborted. use NFW here since we don't want to
                        // crash VS on explicitly killing OOP.
                        task.Exception.ReportServiceHubNFW("JsonRpc Invoke Failed");

                        throw;
                    }
                }
        }