public async Task TestAwaitTimeoutAndReceivedResult()
        {
            var x = new ResultCallback();

            Assert.False((bool)await x.Wait(TimeSpan.FromMilliseconds(100)));
            x.ReceivedResult(CallTransmissionResponseType.Exception, null, 0); //no exception
        }
        public async Task TestReceivedResultAfterDispose()
        {
            var x = new ResultCallback();

            Assert.False(await x.Wait(TimeSpan.FromMilliseconds(50)));
            x.Dispose();
            x.ReceivedResult(CallTransmissionResponseType.MethodExecuted, null, 0);
        }
        public async Task TestAwaitWorks()
        {
            var testData = new byte[12];

            StaticRandom.NextBytes(testData);

            var x = new ResultCallback();
            await Task.Delay(TimeSpan.FromMilliseconds(50))
            .ContinueWith(task => x.ReceivedResult(CallTransmissionResponseType.MethodExecuted, testData, 4));

            await x.Wait(TimeSpan.FromSeconds(1));

            Assert.Equal(CallTransmissionResponseType.MethodExecuted, x.ResponseType);
            Assert.Equal(testData, x.Data);
            Assert.Equal(4, x.Offset);
        }
Exemple #4
0
        private async Task <object> SendMethodCall(MethodCache methodCache, object[] parameters)
        {
            if (methodCache == null)
            {
                throw new ArgumentException("The parameter cannot be null.", nameof(methodCache));
            }
            if (methodCache == null)
            {
                throw new ArgumentException("The parameter cannot be null.", nameof(parameters));
            }

            //PROTOCOL
            //CALL:
            //HEAD      - 4 bytes                   - Identifier, ASCII (NTC1)
            //HEAD      - integer                   - callback identifier
            //HEAD      - uinteger                  - The method identifier
            //HEAD      - integer * parameters      - the length of each parameter
            //--------------------------------------------------------------------------
            //DATA      - length of the parameters  - serialized parameters

            var callbackId = (uint)Interlocked.Increment(ref _callIdCounter);

            var buffer = new byte[CustomOffset /* user offset */ + 4 /* Header */ + 4 /* Callback id */ +
                                  4 /* method id */ + parameters.Length * 4 /* parameter meta */ +
                                  EstimatedDataPerParameter * parameters.Length /* parameter data */];
            var bufferOffset = CustomOffset + 12 + parameters.Length * 4;

            for (var i = 0; i < parameters.Length; i++)
            {
                var metaOffset      = CustomOffset + 12 + i * 4;
                var parameterLength = _serializer.Serialize(methodCache.ParameterTypes[i],
                                                            ref buffer, bufferOffset, parameters[i]);
                Buffer.BlockCopy(BitConverter.GetBytes(parameterLength), 0, buffer, metaOffset, 4);

                bufferOffset += parameterLength;
            }

            //write header
            buffer[CustomOffset]     = CallProtocolInfo.Header1;
            buffer[CustomOffset + 1] = CallProtocolInfo.Header2;
            buffer[CustomOffset + 2] = CallProtocolInfo.Header3Call;
            buffer[CustomOffset + 3] = CallProtocolInfo.Header4;

            //write callback id
            Buffer.BlockCopy(BitConverter.GetBytes(callbackId), 0, buffer, CustomOffset + 4, 4);

            //method identifier
            Buffer.BlockCopy(BitConverter.GetBytes(methodCache.MethodId), 0, buffer, CustomOffset + 8, 4);

            var callback     = new ResultCallback();
            var callbackWait = callback.Wait(WaitTimeout);

            _callbacks.TryAdd(callbackId, callback);                               //impossible that this goes wrong

            OnSendData(new ArraySegment <byte>(buffer, 0, bufferOffset)).Forget(); //no need to await that

            using (callback)
            {
                if (!await callbackWait.ConfigureAwait(false))
                {
                    _callbacks.TryRemove(callbackId, out var _);
                    throw new TimeoutException("The method call timed out, no response received.");
                }

                switch (callback.ResponseType)
                {
                case CallTransmissionResponseType.MethodExecuted:
                    return(null);

                case CallTransmissionResponseType.ResultReturned:
                    return(_serializer.Deserialize(methodCache.ReturnType, callback.Data,
                                                   callback.Offset));

                case CallTransmissionResponseType.Exception:
                    var up = _serializer.DeserializeException(callback.Data, callback.Offset);
                    throw up;

                case CallTransmissionResponseType.MethodNotImplemented:
                    throw new NotImplementedException("The remote method is not implemented.");

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
        public async Task TestWaitTimeout()
        {
            var x = new ResultCallback();

            Assert.False(await x.Wait(TimeSpan.FromMilliseconds(200)));
        }