Exemple #1
0
 private void SendOnMainThread(ServerCommand command, IEnumerable <byte> data)
 {
     if (IsOnMainThread)
     {
         Send(command, data);
     }
     else
     {
         _syncronizationContext.Send(ctx => Send(command, data), null);
     }
 }
        /// <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));
            }

            AssertRunning();

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

            _callbacks[name] = new Callback(target, methodInfo, name, parameters, this);

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

            // TODO: Only call on main thread
            var ptr = Marshal.AllocHGlobal(data.Length);

            Marshal.Copy(data, 0, ptr, data.Length);

            if (IsOnMainThread)
            {
                Interop.RegisterCallback(ptr);
            }
            else
            {
                _syncronizationContext.Send(ctx => Interop.RegisterCallback(ptr), null);
            }

            Marshal.FreeHGlobal(ptr);
        }