< Summary - CoreWCF Coverage — PR #1766

Information
Class: CoreWCF.Runtime.TaskHelpers
Assembly: CoreWCF.Kafka.Client
File(s): /home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Kafka.Client/src/CoreWCF/Runtime/TaskHelpers.cs
Line coverage
39%
Covered lines: 20
Uncovered lines: 31
Coverable lines: 51
Total lines: 149
Line coverage: 39.2%
Branch coverage
33%
Covered branches: 6
Total branches: 18
Branch coverage: 33.3%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
ToApm(...)100%110%
ToApm(...)0%440%
ToApm(...)100%44100%
ToApmEnd(...)0%220%
ToApmEnd(...)50%2266.66%
.ctor(...)100%11100%
GetResult()100%11100%
ExecuteCallback()50%22100%
.ctor(...)100%110%
GetResult()100%110%
ExecuteCallback()0%220%

File(s)

/home/runner/work/CoreWCF/CoreWCF/src/CoreWCF.Kafka.Client/src/CoreWCF/Runtime/TaskHelpers.cs

#LineLine coverage
 1// Licensed to the .NET Foundation under one or more agreements.
 2// The .NET Foundation licenses this file to you under the MIT license.
 3
 4using System;
 5using System.Threading;
 6using System.Threading.Tasks;
 7
 8namespace CoreWCF.Runtime
 9{
 10    internal static class TaskHelpers
 11    {
 12        // Helper method when implementing an APM wrapper around a Task based async method which returns a result.
 13        // In the BeginMethod method, you would call use ToApm to wrap a call to MethodAsync:
 14        //     return MethodAsync(params).ToApm(callback, state);
 15        // In the EndMethod, you would use ToApmEnd<TResult> to ensure the correct exception handling
 16        // This will handle throwing exceptions in the correct place and ensure the IAsyncResult contains the provided
 17        // state object
 18        public static IAsyncResult ToApm<T>(this Task<T> task, AsyncCallback callback, object state)
 019            => ToApm<T>(new ValueTask<T>(task), callback, state);
 20
 21        /// <summary>
 22        /// Helper method to convert from Task async method to "APM" (IAsyncResult with Begin/End calls)
 23        /// </summary>
 24        public static IAsyncResult ToApm<T>(this ValueTask<T> valueTask, AsyncCallback callback, object state)
 25        {
 026            var result = new AsyncResult<T>(valueTask, callback, state);
 027            if (result.CompletedSynchronously)
 28            {
 029                result.ExecuteCallback();
 30            }
 031            else if (callback != null)
 32            {
 33                // We use OnCompleted rather than ContinueWith in order to avoid running synchronously
 34                // if the task has already completed by the time we get here.
 35                // This will allocate a delegate and some extra data to add it as a TaskContinuation
 036                valueTask.ConfigureAwait(false)
 037                    .GetAwaiter()
 038                    .OnCompleted(result.ExecuteCallback);
 39            }
 40
 041            return result;
 42        }
 43
 44        /// <summary>
 45        /// Helper method to convert from Task async method to "APM" (IAsyncResult with Begin/End calls)
 46        /// </summary>
 47        public static IAsyncResult ToApm(this Task task, AsyncCallback callback, object state)
 48        {
 3549            var result = new AsyncResult(task, callback, state);
 3550            if (result.CompletedSynchronously)
 51            {
 1852                result.ExecuteCallback();
 53            }
 1754            else if (callback != null)
 55            {
 56                // We use OnCompleted rather than ContinueWith in order to avoid running synchronously
 57                // if the task has already completed by the time we get here.
 58                // This will allocate a delegate and some extra data to add it as a TaskContinuation
 1759                task.ConfigureAwait(false)
 1760                    .GetAwaiter()
 1761                    .OnCompleted(result.ExecuteCallback);
 62            }
 63
 3564            return result;
 65        }
 66
 67        public static T ToApmEnd<T>(this IAsyncResult asyncResult)
 68        {
 069            if (asyncResult is AsyncResult<T> asyncResultInstance)
 70            {
 071                return asyncResultInstance.GetResult();
 72            }
 73            else
 74            {
 75                // throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 76                //     new ArgumentException(SRCommon.SFxInvalidCallbackIAsyncResult));
 077                throw new ArgumentException(nameof(asyncResult));
 78            }
 79        }
 80
 81        public static void ToApmEnd(this IAsyncResult asyncResult)
 82        {
 3583            if (asyncResult is AsyncResult asyncResultInstance)
 84            {
 3585                asyncResultInstance.GetResult();
 86            }
 87            else
 88            {
 89                // throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(
 90                //     new ArgumentException(SRCommon.SFxInvalidCallbackIAsyncResult));
 091                throw new ArgumentException(nameof(asyncResult));
 92            }
 93        }
 94
 95        private class AsyncResult : IAsyncResult
 96        {
 97            private readonly Task _task;
 98            private readonly AsyncCallback _asyncCallback;
 99
 35100            public AsyncResult(Task task, AsyncCallback asyncCallback, object asyncState)
 101            {
 35102                _task = task;
 35103                _asyncCallback = asyncCallback;
 35104                AsyncState = asyncState;
 35105                CompletedSynchronously = task.IsCompleted;
 35106            }
 107
 35108            public void GetResult() => _task.GetAwaiter().GetResult();
 109
 35110            public void ExecuteCallback() => _asyncCallback?.Invoke(this);
 111
 17112            public object AsyncState { get; }
 0113            WaitHandle IAsyncResult.AsyncWaitHandle => ((IAsyncResult)_task).AsyncWaitHandle;
 114
 105115            public bool CompletedSynchronously { get; }
 0116            public bool IsCompleted => _task.IsCompleted;
 117        }
 118
 119        internal class AsyncResult<T> : IAsyncResult
 120        {
 121            private readonly ValueTask<T> _task;
 122            private readonly AsyncCallback _asyncCallback;
 123
 0124            public AsyncResult(ValueTask<T> task, AsyncCallback asyncCallback, object asyncState)
 125            {
 0126                _task = task;
 0127                _asyncCallback = asyncCallback;
 0128                AsyncState = asyncState;
 0129                CompletedSynchronously = task.IsCompleted;
 0130            }
 131
 0132            public T GetResult() => _task.GetAwaiter().GetResult();
 133
 0134            public bool IsFaulted => _task.IsFaulted;
 0135            public AggregateException Exception => _task.AsTask().Exception;
 136
 137            // Calls the async callback with this as parameter
 0138            public void ExecuteCallback() => _asyncCallback?.Invoke(this);
 0139            public object AsyncState { get; }
 140
 0141            WaitHandle IAsyncResult.AsyncWaitHandle => !CompletedSynchronously
 0142                ? ((IAsyncResult)_task.AsTask()).AsyncWaitHandle
 0143                : throw new NotImplementedException();
 144
 0145            public bool CompletedSynchronously { get; }
 0146            public bool IsCompleted => _task.IsCompleted;
 147        }
 148    }
 149}