Is multicast delegate create new reference for each chaining? or its a value type (MSDN says otherwise)? I don't understand, please take look at the following code.
using System;
class TestClass
{
static void Main()
{
Action origin = new Action(() => { Console.WriteLine("1st line"); });
Action copyFromOrigin;
copyFromOrigin = origin;
origin += new Action(() => { Console.WriteLine("2nd line"); });
copyFromOrigin.Invoke();
//result is "1st line", why the "2nd line" is missing?
//shouldn't the copyFromOrigin is referencing the origin?
Console.ReadKey();
}
}
Delegates are immutable....
When you add a new handler a new delegate is created.
Under the hood it calls the Delegate.Combine Method
Concatenates the invocation lists of two delegates.
Returns
A new delegate with an invocation list that concatenates the
invocation lists of a and b in that order. Returns a if b is null,
returns b if a is a null reference, and returns a null reference if
both a and b are null references.
You can see it in action here
Action action = <>c.<>9__0_0 ?? (<>c.<>9__0_0 = new Action(<>c.<>9.<M>b__0_0));
Action action2 = action;
action = (Action)Delegate.Combine(action, <>c.<>9__0_1 ?? (<>c.<>9__0_1 = new Action(<>c.<>9.<M>b__0_1)));
action2();
Console.ReadKey();
Because it's immutable type and each assignment creates new instance copied from original one. Note it's still reference type but just of special kind.
Related
I just started with .net core and found Action<T> used everywhere. I have provide sample code from Swagger code block below. My question is what is the use of using Action<T> here? I need to pass config data. How does Swagger extract that configuration data?
services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new Info
{
Version = "v1",
Title = "My API",
Description = "My First ASP.NET Core Web API",
TermsOfService = "None",
Contact = new Contact() { Name = "Talking Dotnet", Email = "x#x.com", Url = "www.x.com" }
});
});5
It's a lambda function which does not return anything. You could supply a void returning method there.
Here it's just used so that you can supply a function that does something with T. It means the library can create a default options object and give you a way of modifying it.
The method would be doing something like
public void AddFoo(Action<FooOptions> configure) {
// Create a default configuration object
var options = new FooOptions();
// Let the action modify it
configure(options);
// Do something with the now configured options
}
When you see a variable or a parameter of type Action, that means it is a reference to a method call. For example:
//Declare a method with no parameters
void ShowMessage()
{
Console.WriteLine("Hello world");
}
//Store a reference to that method in x
Action x = ShowMessage;
//Call that method
x(); //Displays "hello world"
Using a lambda expression, you can also define the method body inline, like this:
//Declare a lambda expression and store a reference to it in x
Action x = () => Console.WriteLine("Hello world");
//Call that method
x(); //Displays "hello world"
Now what if you need to store a reference to a method that takes parameters? Well, Action<T> is generic, meaning that various kinds of Action<T> can take parameters of different types. For example, an Action<string> can accept a string parameter.
void ShowMessage(string message)
{
Console.WriteLine(message);
}
Action<string> x = ShowMessage;
x("Hello world"); //Displays "Hello world"
Or as a Lambda:
Action<string> x = message => Console.WriteLine(message);
x("Hello world"); //Displays "Hello world"
When a method accepts an action as an argument, is is typically going to be used as a callback. For example, LINQ's Where method accepts a delegate that is executed for each item in a list and uses its output to determine whether the item should be included in the results.
With AddSwaggerGen you are providing a reference to a method that Swashbuckle will call at some point. I believe the method in this case is supposed to generate Swagger (typically using SwaggerDoc).
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.
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.
I am trying to grasp the concept of delegate and I grabbed the following code from a SO post.
What I am not understanding is what is happening inside of Main method. I can tell from a surfacial look at it there is a new delegate object and methods with matching arguments and return types are being called by referencing the delegate object. I want to know what these three lines are doing specifically:
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
Here is the actual code:
using System;
public delegate void Valid(int a);
public class Test {
public const int MAX_VALUE = 255;
public const int MIN_VALUE = 10;
public static void checkInt(int a) {
Console.Write("checkInt result of {0}: ", a);
if (a < MAX_VALUE && a > MIN_VALUE)
Console.WriteLine("max and min value is valid");
else
Console.WriteLine("max and min value is not valid");
}
public static void checkMax(int a) {
Console.Write("checkMax result of {0}: ", a);
if (a < MAX_VALUE)
Console.WriteLine("max value is valid");
else
Console.WriteLine("max value is not valid");
}
public static void checkMin(int a) {
Console.Write("checkMin result of {0}: ", a);
if (a > MIN_VALUE)
Console.WriteLine("min value is valid");
else
Console.WriteLine("min value is not valid");
Console.WriteLine("");
}
}
public class Driver {
public static void Main(string [] args) {
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
v1(1);
v1(10);
v1(20);
v1(30);
v1(254);
v1(255);
v1(256);
Console.ReadLine();
}
}
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
That code sets up a Multi-Cast Delegate. It means that, when you execute v1 with a parameter (which is what's happening in the Main method), it will pass that parameter to all three check methods and execute them in sequence. The method parameter is specified in the delegate declaration.
Valid v1 = new Valid(Test.checkInt);
v1 += new Valid(Test.checkMax);
v1 += new Valid(Test.checkMin);
The first line declares a new delegate v1 (analogous to a function pointer). For now, its pointing to Test.checkInt.
Then with the += operator you make the delegate point to a second method, promoting it to a MulticastDelegate. The same thing happens on the third line.
On the following lines you invoke the delegate, which in turn invokes all methods that it is pointing to. The parameters passed to the delegate, will be passed to each of these methods.
The three lines in question define delegates conforming to the signature of Valid, using methods with the corresponding return type and parameters. The += operator makes a so-called multicast delegate from regular delegates. When a multicast delegate is called, its implementation calls the component delegates, producing the effects that you see.
The += operator for delegates is a way to combine delegates. It will create a new delegate that, when called, will invoke all of the methods that the delegate would have invoked before, in addition to this new method.
In this case, after executing those lines of code, invoking v1 will execute Test.checkInt, Test.checkMax, and Test.checkMin.
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.