Calling methods selected in a ListBox - c#

I have an issue with a Windows Forms application that I am creating. The application is supposed to be an integration testing application. Essentially, it's supposed to test the methods that utilize lots of web services in one of my classes. I am loading the methods from the class I want to test via reflection, and am doing so like this:
private List<string> GetMethods(Type type)
{
return (from method in type.GetMethods() where method.IsPublic &&
method.ReturnType == typeof(void) select method.Name).ToList();
}
This returns a list of the methods from that class that have been created to test the web services and places them in a ListBox where the user can select as many methods as he/she likes. My confusion comes in here. What I would like to do is get the methods selected by the user and execute the corresponding method X amount of times (there is a text box for entering the number of times to execute a method on the form as well). I can't figure out how to execute these methods based on the name of the method I got through reflection. I've tried something like this, but I know it's not right:
private void RunMethods(Type type)
{
var tester = new ClassToTest();
foreach(var item in lstMethodList.SelectedItems)
{
foreach(var method in type.GetMethods())
{
if(String.Equals(item.ToString(), method.Name))
{
ThreadStart ts = new ThreadStart(method.Name);
Thread thread1 = new Thread(ts);
thread1.Start();
}
}
}
}
This won't even compile, as a ThreadStart requires a method name as a parameter. Is there any way that this is possible to do? Maybe I'm going about it wrong logically, but I'd like to create a thread for each method that needs to be run and execute that method however many times the user specifies. This is supposed to be a way of doing integration testing along with some load testing to see what the web service can handle.

You can use something like this to get the methods you want:
private List<MethodInfo> GetMethods(Type type)
{
return (from method in type.GetMethods()
where method.IsPublic &&
method.ReturnType == typeof(void)
select method).ToList();
}
Then if you want to call the methods in separate threads you would write (will work only if the methods are static):
foreach(MethodInfo mi in GetMethods(SomeType) {
MethodInfo tempMi = mi;
Action myAction = (Action) Delegate.CreateDelegate(typeof(Action), tempMi);
ThreadStart ts = new ThreadStart(myAction);
Thread thread1 = new Thread(ts);
thread1.Start();
}
Or you would write (only if the methods have strictly no parameters, beware of inherited methods which may take parameters!):
foreach (MethodInfo mi in GetMethods(type))
{
MethodInfo tempMi = mi; //modified closure
object o = Activator.CreateInstance( type );
Action myAction = delegate() { tempMi.Invoke(o, null); };
ThreadStart ts = new ThreadStart(myAction);
Thread thread1 = new Thread(ts);
thread1.Start();
}
If the methods take parameters, you'd have to pass an array of object( object [] { ... } ) instead of null (in the Invoke method called on the current MethodInfo) accordingly; with of course corrects objects in the array.
It would actually be better if you take a List of Thread and add a new Thread in it for each MethodInfo in the list so you can keep control on them afterwards (like if you want to stop one). A HashMap would also be a good choice, the key being the MethodInfo or the Action and the value being the associated Thread.

You can create an instance of your class using Activator.
Then you can call one of its methods using Invoke.
Something like this should work:
private void RunMethods(Type type)
{
foreach( var item in lstMethodList.SelectedItems )
{
foreach( var method in type.GetMethods() )
{
if( String.Equals( item.ToString(), method.Name))
{
MethodInfo capturedMethod = method;
var t = new Thread( () => ThreadMain( type, capturedMethod ) );
t.Start();
}
}
}
}
static void ThreadMain( Type type, MethodInfo mi )
{
object o = Activator.CreateInstance( type );
object[] parameters = new object[] { };
mi.Invoke( o, parameters );
}
I've assumed the class being tested has a parameter-less constructor.

You can implement a private dictionary which holds the MethodInfos and Method name.
private Dictionary<string, MethodInfo> methodList;
private List<string> GetMethods(Type type)
{
methodList = new Dictionary<string, MethodInfo>();
type.GetMethods().Where(m=>m.IsPublic && m.ReturnType.Equals(typeof(void))).ToList().ForEach(m=>
methodList.Add(m.Name,m)
);
return methodList.Keys.Select(k => k).ToList();
}
on selecting the dropdown, you can find the method in the dictionary and execute it.

Related

How to call functions from data structure?

I would like to be able to describe some actions as function calls represented in a datastructure. Then I would like to be able to loop through the data structure and call the functions.
This pseudo-code describes what I would like to achieve:
static void Main(string[] args)
{
Action[] actions = new Action[]
{
new Action(DoAction1(5)),
new Action(DoAction1(7)),
new Action(DoAction2("100201")),
};
foreach (Action action in actions)
{
action.<Run the action function>;
}
}
public static void DoAction1(int x)
{
}
public static void DoAction2(string x)
{
}
It kind of looks like delegates, but not quite.
Any ideas on how to achieve this?
This is what you're looking for?
Action[] actions = new Action[]
{
new Action(()=>DoAction1(5)),
new Action(()=>DoAction1(7)),
new Action(()=>DoAction2("100201"))
};
foreach (Action action in actions)
{
action();
}
The Action class in .net allows you to directly assign lambdas
var actions = new List<Action>
{
() => DoAction1(5),
() => DoAction1(7),
() => DoAction2("100201"),
};
then executing an array of actions can be done like :-
actions.ForEach(a => a());
then you can add more actions to the list
actions.Add(() => DoAction2("blah blah"));
may be you can use reflection
var methodNames = typeof(MyType).GetMethods(BindingFlags.Public |
BindingFlags.Static)
.Select(x => x.Name)
.Distinct()
.OrderBy(x => x);
OR
foreach (var property in yourObject.GetType().GetProperties())
{
if (property.PropertyType.GetInterfaces().Contains(typeof(IEnumerable)))
{
foreach (var item in (IEnumerable)property.GetValue(yourObject, null))
{
//do stuff
}
}
}
Since you seem not to want to use the Action class, you can check out the SharpByte codebase, specifically the SharpByte.Dynamic namespace. It allows evaluating statements and executing scripts with just a single method call, like this:
someContextObject.Execute("[executable code here]");
However, you can use it another way which may be what you're looking for. When you execute one of those dynamic compilation/execution extension methods, here's what's actually happening (paraphrased):
IExecutable executable = ExecutableFactory.Default.GetExecutable(ExecutableType.Script, "[source code here]", optionalListOfParameterNames, optionalListOfNamespaces);
If you wanted to evaluate an expression/function instead of run multiple-lined statements, you'd use ExecutableType.Expression . The main point is that you can keep a reference around to an IExecutable object and run it as many times as you like, passing different parameter values each time. You can also copy IExecutable objects freely using the .Copy() method of each; they are designed to be thread-safe but lightweight, and references or copies could thus be placed in a data structure for further (re)use. This post explains a bit more.

Effective way to invoke generic interface method in runtime

I'm working on the some kind of EventSourcing architecture and have 2 main concepts in my app - events and handlers.
Events example:
class NewRecordCreated: EventMessage {...}
And there some handlers looks like:
class WriteDBHandler: IEventHandler<NewRecordCreated>, IEventHandler<RecordUpdated> {
public void Handle(NewRecordCreated eventMessage) {...}
public void Handle(RecordUpdated eventMessage) {...}
}
And also I have custom implementation of queue protocol which dispatch events to proper handlers. So basically on app startup I parse assembly and create mapping between event and handlers based on types.
So when I actually dispatching events to handlers I based on event type getting chain of handler's types - something like var handlerChain = [typeof(WriteDbHandler), typeof(LogHandler), typeof(ReadModelUpdateHandler)] and for each of those handlers I need to invoke it's instance, then cast it to proper interface (IEventHandler<>) and than invoke Handle method.
But I can't cast to generic interface, since it's not possible. I think about options of implementing non generic version of interface, but it's seems quite unpleasant for me to add extra method implementation each time, especially if there no any real reasons for it.
I think about dynamic invocation or reflection, but both of this variants seems have performance issues. Maybe you could advice me some suitable alternatives?
Using reflection
Rather than trying to cast to IEventHandler<>, you can instead use reflection to get a reference to the method you need to invoke. The code below is a good example. It simplifies the "queue protocol" for sake of brevity, but it should sufficiently illustrate the reflection that you need to do.
class MainClass
{
public static void Main(string [] args)
{
var a = Assembly.GetExecutingAssembly();
Dictionary<Type, List<Type>> handlerTypesByMessageType = new Dictionary<Type, List<Type>>();
// find all types in the assembly that implement IEventHandler<T>
// for some value(s) of T
foreach (var t in a.GetTypes())
{
foreach (var iface in t.GetInterfaces())
{
if (iface.GetGenericTypeDefinition() == typeof(IEventHandler<>))
{
var messageType = iface.GetGenericArguments()[0];
if (!handlerTypesByMessageType.ContainsKey(messageType))
handlerTypesByMessageType[messageType] = new List<Type>();
handlerTypesByMessageType[messageType].Add(t);
}
}
}
// get list of events
var messages = new List<EventMessage> {
new NewRecordCreated("one"),
new RecordUpdated("two"),
new RecordUpdated("three"),
new NewRecordCreated("four"),
new RecordUpdated("five"),
};
// process all events
foreach (var msg in messages)
{
var messageType = msg.GetType();
if (!handlerTypesByMessageType.ContainsKey(messageType))
{
throw new NotImplementedException("No handlers for that type");
}
if (handlerTypesByMessageType[messageType].Count < 1)
{
throw new NotImplementedException("No handlers for that type");
}
// look up the handlers for the message type
foreach (var handlerType in handlerTypesByMessageType[messageType])
{
var handler = Activator.CreateInstance(handlerType);
// look up desired method by name and parameter type
var handlerMethod = handlerType.GetMethod("Handle", new Type[] { messageType });
handlerMethod.Invoke(handler, new object[]{msg});
}
}
}
}
I compiled this and ran it on my machine and got what I believe are the correct results.
Using run-time code generation
If reflection is not fast enough for your purposes, you can compile code on-the-fly for each input message type and execute that.
The System.Reflection.Emit namespace has facilities for doing just that.
You can define a dynamic method (not to be confused with the dynamic keyword, which is something else), and emit a sequence if IL opcodes that will run each handler in the list in sequence.
public static Dictionary<Type, Action<EventMessage>> GenerateHandlerDelegatesFromTypeLists(Dictionary<Type, List<Type>> handlerTypesByMessageType)
{
var handlersByMessageType = new Dictionary<Type, Action<EventMessage>>();
foreach (var messageType in handlerTypesByMessageType.Keys)
{
var handlerTypeList = handlerTypesByMessageType[messageType];
if (handlerTypeList.Count < 1)
throw new NotImplementedException("No handlers for that type");
var method =
new DynamicMethod(
"handler_" + messageType.Name,
null,
new [] { typeof(EventMessage) });
var gen = method.GetILGenerator();
foreach (var handlerType in handlerTypeList)
{
var handlerCtor = handlerType.GetConstructor(new Type[0]);
var handlerMethod =
handlerType.GetMethod("Handle", new Type[] { messageType });
// create an object of the handler type
gen.Emit(OpCodes.Newobj, handlerCtor);
// load the EventMessage passed as an argument
gen.Emit(OpCodes.Ldarg_0);
// call the handler object's Handle method
gen.Emit(OpCodes.Callvirt, handlerMethod);
}
gen.Emit(OpCodes.Ret);
var del = (Action<EventMessage>)method.CreateDelegate(
typeof(Action<EventMessage>));
handlersByMessageType[messageType] = del;
}
}
Then, instead of invoking the handlers with handlerMethod.Invoke(handler, new object[]{msg}), you just call the delegate like any other, with handlersByMessageType[messageType](msg).
Full code listing here.
The actual code generation is done in the GenerateHandlerDelegatesFromTypeLists method.
It instantiates a new DynamicMethod, gets its associated ILGenerator, and then emits opcodes for each handler in turn.
For each handler type, it will instantiate a new object of that handler type, load the event message onto the stack, and then execute the Handle method for that message type on the handler object.
This is of course assuming that the handler types all have zero-parameter constructors.
If you need to pass arguments to the constructors, though, you'll have to modify it considerably.
There are other ways to speed this up even more.
If you relax the requirement to create a new handler object with every message, then you could just create the objects while generating the code, and load them.
In that case, replace gen.Emit(OpCodes.Newobj, handlerCtor) with gen.Emit(OpCodes.Ldobj, handlerObjectsByType[handlerType]).
That gives you two benefits:
1. you're avoiding an allocation on every message
2. you can instantiate the objects any way you want when you populate the handlerObjectsByType dictionary. You can even use constructors with parameters or factory methods.

Polymorphic way to call different functions with an allocated thread

I have a class with a set of functions that differ in the number of parameters and the parameter types. I've been trying to figure out a way to invoke a call to a desired function inside an allocated thread.
What's a simple way of doing this? I've looked into System.Action, but that requires the parameters to be known. I've also gone over TaskFactory and TPL, but from the examples I've seen, I can't put together the solution in my head.
What I want to eventually do is queue up jobs that will be executed by a limited number of threads. The jobs performed are simple HTTP requests.
I feel like this has been done before and has a simple solution, but it has eluded me for weeks. I'm hoping for an elegant way of doing it instead of a lot of complex code.
I'm also trying to implement MEF plugins to make matters worse.
public bool AddThreads(int numOfThreads)
{
try
{
// Exit if no plugin type is set
if (PluginType == "") return false;
int totalThreads = numOfThreads + threads.Count;
for (int i = threads.Count; i < totalThreads; i++)
{
// Create an instance of the MEF plugin
var task = PluginHandler.CreateInstance(PluginType);
threads.Add(task);
task.ThreadId = i;
task.OnStatusChange += new TaskerPlugin.EventHandler(ChangeStatus);
task.OnActionComplete += new TaskerPlugin.EventHandler(ReportComplete);
task.OnActionSuccess += new TaskerPlugin.EventHandler(ReportSuccess);
task.OnActionFailure += new TaskerPlugin.EventHandler(ReportFailure);
task.OnActionAttempt += new TaskerPlugin.EventHandler(ReportAttempt);
task.OnActionError += new TaskerPlugin.EventHandler(ReportError);
task.OnActionCancelled += new TaskerPlugin.EventHandler(ReportCancellation);
task.OnActionBegin += new TaskerPlugin.EventHandler(ReportStartOfTask);
task.OnActionEnd += new TaskerPlugin.EventHandler(ReportEndOfTask);
// Do work from plugin
// This is where I'd like to call different
// functions possibly inside Start()
task.Start();
}
return true;
}
catch (Exception)
{
return false;
}
}
Current code calling the function:
private void CreateThreads(int threadCount)
{
// taskMan is a class variable to queue more jobs in the future
taskMan = new TaskManager(PLUGIN_FOLDER)
{
PluginType = PLUGIN_TYPE,
UseProxies = (_config.IpSolution == "Proxies" || _config.IpSolution == "Proxy URL")
};
taskMan.AddThreads(threadCount);
}
I want to eventually just call a function to add a job to it with a predefined number of threads:
private void AddJob(string pluginName, string methodName, List<string> args)
I'd prefer not just using a string list to put all of my arguments in, but I don't really know of another way of doing it. Maybe a list of objects which I then cast later? Both these ideas are very messy...
I am assuming that AddJob is the overloaded method that you need to call with different parameters.
You might have to tweak your PluginHandler.CreateInstance(PluginType) method to do something like this while creating the task, this would allow you to execute any method you need in the task that you create..
Task task = new Task(() =>
{
classInstance.YourMethod("some param1", some other param2));
}
Further with some reflection..
var classInstance = new YourClass();
Type type = classInstance.GetType();
MethodInfo methodInfo = type.GetMethod("AddJob");
object[] parametersArray = new object[] { "some param1", "some parma2" };
methodInfo.Invoke(methodInfo, parametersArray);
and finally,
Task task = new Task(() =>
{
var classInstance = new YourClass();
Type type = classInstance.GetType();
MethodInfo methodInfo = type.GetMethod("AddJob");
object[] parametersArray = new object[] { "some param1", "some parma2" };
methodInfo.Invoke(classInstance, parametersArray);
}
In case the AddJob method is present in the current class itself, there could be little changes to the code.

Passing a method as a parameter with zero or more parameters for the passed in method?

I'm trying to code what I've called a 'trigger'. They take an object, a function and some kind of activation criteria. Once activated, it runs the method on that object.
Here's a basic stripped down example. It works as expected for now. An example usage would be:
SomeObject myObj = new SomeObject();
MyTrigger trigger = new MyTrigger(myObj, "Delete");
trigger.Activate(); // calls myObj.Delete();
Now where I've called Invoke with null is where parameters can normally go (I think). The problem I'm having is getting the 'zero or more paramters' as a single parameter in the function declaration. I need a thrid parameter when creating MyTrigger that would be the parameters to pass during the Invoke.
Or is there an even better way to do it? I.e. Can I somehow pass the object, the function call and the parameters as a single parameter? Maybe two parameters?
You have to use delegates.
// rewrite your trigger constructor like this
class MyTrigger<TTarget>
{
public MyTrigger(TTarget target, Action<TTarget> action);
public void Activate()
{
this._action(this._target);
}
}
// now call it with or without parameters
SomeObject myObj = new SomeObject();
var trigger = new MyTrigger<SomeObject>(myObj, o => o.Delete(1234));
trigger.Activate();
You can also create a static helper class to make the creation code slightly simpler to write:
static class MyTrigger
{
public MyTrigger<TTarget> Create<TTarget>(TTarget target, Action<TTarget> action)
{
return new MyTrigger<TTarget>(target, action);
}
}
// now write the initialization code like this (you don't have to specify the type parameter anymore):
var trigger = MyTrigger.Create(myObj, o => o.Delete());
You could use the params keyword:
public Trigger(object targetObject, string methodName, params object[] parameters)
{
//"parameters" here will be an array of length 0 if no parameters were passed
}
MyTrigger trigger = new MyTrigger(myObj, "Delete"); //no parameters
MyTrigger trigger = new MyTrigger(myObj, "Delete", param1); //one parameter
MyTrigger trigger = new MyTrigger(myObj, "Delete", param1, param2); //two parameters
But I prefer Knagis' answer because it will also provide you compile-time safety (and likely the Trigger class will be far simplified and ditch any reflection that you probably have in there.)

std::bind equivalent in C# or VB.NET

I am in the process of refactoring "synchronous" code (i.e. uses Windows events to wait until some other thread finished doing something) to "asynchronous" code (using delegates to implement a callback mechanism).
In the sync code, I sometimes have local variables that I need to use after the wait is over. When code like that goes async, those local variables are lost (the callback handler can't access them). I can store them as class attributes, but it feels wasteful.
In C++, I use std::bind to work around this. I just add as many parameters as local variables needed to the callback handler, and bind them when I call the async method. For example, let's say that the async method callback receives an object of type CallbackParam and the caller uses two local variables of type LocalA and LocalB.
void AsyncClass::MethodWhichCallsAsyncMethod(){
LocalA localVarA;
LocalB localVarB;
// OnAsyncMethodDone will need localVarA and localVarB, so we bind them
AsyncMethod( std::bind( &AsyncClass::OnAsyncMethodDone, this, std::placeholders::_1, localVarA, localVarB ) );
}
void AsynClass::AsyncMethod( std::function<void(CallbackParam)> callback ){
CallbackParam result;
//Compute result...
if( callback )
callback( result );
}
void AsyncClass::OnAsyncMethodDone( CallbackParam p, LocalA a, LocalB b ){
//Do whatever needs to be done
}
Is there some sort of equivalent to this in C# and VB.NET? Using delegates or something else?
UPDATE: For completeness' sake, here is the C# equivalent of my example based on #lasseespeholt's answer:
using System;
public class AsyncClass {
public void MethodWhichCallsAsyncMethod() {
var a = new LocalA();
var b = new LocalB();
//Anonymous callback handler (equivalent to AsyncClass::OnAsyncMethodDone)
Action<CallbackParam> callback = result => {
//Do what needs to be done; result, a and b can be accessed
};
AsyncMethod( callback );
}
private void AsyncMethod( Action<CallbackParam> callback ) {
var result = new CallbackParam();
//Compute result...
if( callback != null )
callback( result );
}
}
UPDATE: This should almost certainly not be used. Use the async/await keywords in C#
You can exploit closures like the following:
void MethodWhichCallsAsyncMethod()
{
int foo = 1;
AsyncCallback callback = result =>
{
Console.WriteLine(foo); // Access to foo
};
AsyncMethod(callback);
}
void AsyncMethod(AsyncCallback callback)
{
IAsyncResult result = null; // Compute result
callback(result);
}
The compiler generates a class which contains "foo" so you don't save anything with this approach, but it's clean.

Categories

Resources