Ejemplo n.º 1
0
        /// <summary>
        ///     Registers a callback with the specified <paramref name="name" />. When the callback is called, the specified
        ///     <paramref name="methodInfo" /> will be invoked on the specified <paramref name="target" />.
        /// </summary>
        /// <param name="name">The name af the callback to register.</param>
        /// <param name="target">The target on which to invoke the method.</param>
        /// <param name="methodInfo">The method information of the method to invoke when the callback is called.</param>
        /// <param name="parameters">The parameters of the callback.</param>
        public void RegisterCallback(string name, object target, MethodInfo methodInfo, CallbackParameterInfo[] parameters)
        {
            if (name == null)
            {
                throw new ArgumentNullException(nameof(name));
            }
            if (target == null)
            {
                throw new ArgumentNullException(nameof(target));
            }
            if (methodInfo == null)
            {
                throw new ArgumentNullException(nameof(methodInfo));
            }
            if (parameters == null)
            {
                throw new ArgumentNullException(nameof(parameters));
            }

            AssertRunning();

            if (!Callback.IsValidReturnType(methodInfo.ReturnType))
            {
                throw new CallbackRegistrationException("The method uses an unsupported return type");
            }

            var callback = new Callback(target, methodInfo, name, this);

            if (!callback.MatchesParameters(parameters))
            {
                throw new CallbackRegistrationException("The method does not match the specified parameters.");
            }

            _callbacks[name] = callback;

            var data = ValueConverter.GetBytes(name, Encoding)
                       .Concat(parameters.SelectMany(c => c.GetBytes()))
                       .Concat(new[] { (byte)ServerCommandArgument.Terminator }).ToArray();

            if (IsOnMainThread)
            {
                EnsureBufferSize(data.Length);
                Marshal.Copy(data, 0, _buffer, data.Length);
                Interop.RegisterCallback(_buffer);
            }
            else
            {
                _synchronizationContext.Send(ctx =>
                {
                    EnsureBufferSize(data.Length);
                    Marshal.Copy(data, 0, _buffer, data.Length);
                    Interop.RegisterCallback(_buffer);
                }, null);
            }
        }
 private void SendOnMainThread(ServerCommand command, IEnumerable <byte> data)
 {
     if (IsOnMainThread)
     {
         Send(command, data);
     }
     else
     {
         _synchronizationContext.Send(ctx => Send(command, data), null);
     }
 }