Beispiel #1
0
        private TFunction Create <TFunction>(Type returnType, Type[] parameterTypes, Action <ILWriter> writeFunctionBody)
        {
            if (this.createPhysicalAssembly)
            {
                if (File.Exists(this.assemblySettings.FullPath))
                {
                    File.Delete(this.assemblySettings.FullPath);
                }

                //NOTE: Outputting a physical assembly is just for testing at the moment,
                //      and because it's a separate assembly then the components in FluentBoilerplate
                //      that it may call will have shifty visibility, exposed as 'public' in DEBUG
                //      and 'internal' otherwise. Ideally, find some other way of doing this in order to
                //      remove the conditional visibility.
                var assemblyName = new AssemblyName(this.assemblySettings.Name);
                var assembly     = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave, this.assemblySettings.DirectoryPath);

                var module = assembly.DefineDynamicModule("OutputModule", this.assemblySettings.NameWithExtension);

                var type = module.DefineType("GeneratedFunction", TypeAttributes.Public | TypeAttributes.Class);

                var method = type.DefineMethod("Call",
                                               MethodAttributes.Public | MethodAttributes.Static,
                                               returnType,
                                               parameterTypes);

                var generator = method.GetILGenerator();
                var writer    = new ILWriter(generator);
                writeFunctionBody(writer);

                var concreteType = type.CreateType();
                assembly.Save(this.assemblySettings.NameWithExtension);

                var instance = Activator.CreateInstance(concreteType);
                var call     = concreteType.GetMethod("Call");

                //TFunction is typed so the easiest way to call it in a typed manner is to just
                //funnel everything through a passthrough typed method.

                var callingMethod    = new DynamicMethod(String.Empty, returnType, parameterTypes, true);
                var callingGenerator = callingMethod.GetILGenerator();
                var callingWriter    = new ILWriter(callingGenerator);

                callingWriter.LoadParameterRange(0, parameterTypes.Length);
                callingWriter.StaticMethodCall(call);
                callingWriter.Return();

                return(callingMethod.Create <TFunction>());
            }
            else
            {
                var method    = new DynamicMethod(String.Empty, returnType, parameterTypes, true);
                var generator = method.GetILGenerator();
                var writer    = new ILWriter(generator);
                writeFunctionBody(writer);
                return(method.Create <TFunction>());
            }
        }
Beispiel #2
0
        static void Main(string[] args)
        {
            IExecutorService executorService = Executors.NewFixedThreadPool(THREAD_POOL_SIZE);

            IFuture <int>    f1 = executorService.Submit <int>(GenerateNumbers);
            IFuture <string> f2 = executorService.Submit <string>(PrintCharacters);
            IFuture <int>    f3 = executorService.Submit <int>(PrintArray);

            Console.WriteLine("Numbers generated till {0}", f1.GetResult());
            Console.WriteLine("Original String {0}", f2.GetResult());
            Console.WriteLine("Array Count {0}", f3.GetResult());


            Console.WriteLine("---------");

            Console.WriteLine("Calculating sums...");

            var futures = new List <IFuture <long> >();

            // Call without method arguments
            for (int i = 0; i < 20000; i++)
            {
                SumNumbers     sumNumbers = new SumNumbers(100 + i);
                IFuture <long> submit     = executorService.Submit <long>(sumNumbers.CalculateSum);
                futures.Add(submit);
            }

            long sum = 0;

            foreach (var future in futures)
            {
                sum += future.GetResult();
            }
            Console.WriteLine("Sum = " + sum);

            futures.Clear();

            Console.WriteLine("---------");

            Console.WriteLine("Calculating sums...");

            // Call with method arguments
            for (int i = 0; i < 20000; i++)
            {
                SumNumbers2    sumNumbers2 = new SumNumbers2();
                int            i1          = i; // copy to local variable for closure.
                IFuture <long> submit      =
                    executorService.Submit(() => sumNumbers2.CalculateSumWithArgsAndReturnValue(100 + i1));
                futures.Add(submit);
            }



            sum = 0;
            foreach (var future in futures)
            {
                sum += future.GetResult();
            }
            Console.WriteLine("Sum = " + sum);


            //Say this was created at runtime and we don't know the type or parameter values at compile time.
            object obj = new SumNumbers2();

            object[] parameters = new object[] { 100 };

            //Find the method we want to invoke
            MethodInfo methodInfo = ReflectionUtils.GetMethod(obj.GetType(),
                                                              "CalculateSumWithArgsAndReturnValue",
                                                              ReflectionUtils.GetTypes(parameters));


            //Use expression trees to generate code to invoke method and assign to a delegate.
            LateBoundMethod methodCallback = DelegateFactory.Create(methodInfo);

            IFuture <object> futureLong = executorService.Submit(() => methodCallback(obj, parameters));
            var result = futureLong.GetResult();

            Console.WriteLine("LateBoundMethod Style : Result = " + result);

            ///Use Spring's IL generation to invoke method dynamically.
            IDynamicMethod method = DynamicMethod.Create(methodInfo);

            IFuture <object> futureLongViaDM = executorService.Submit(() => method.Invoke(obj, parameters));
            var resultViaDM = futureLongViaDM.GetResult();

            Console.WriteLine("Spring's IDynamicMethod Style: Result = " + resultViaDM);


            // This will make the executor accept no new threads
            // and finish all existing threads in the queue
            executorService.Shutdown();


            Console.WriteLine("Hit return to exit");
            Console.ReadLine();
        }