I have progress form which delegate:
// in ProgressForm thread
public delegate void executeMethod(object parameters);
private executeMethod method;
public object parameters;
// ...
private void ProgressForm_Shown(object sender, EventArgs e)
{
method.Invoke(parameters);
}
Which way is better (mor efficient or safe) to apply - anonymus delegates call like this:
// in other thread
ProgressForm progress = new ProgressForm();
progress.ExecuteMethod = delegate
{
// to do
}
or using separate method like this:
// in other thread
private void myMethod(object par)
{
// to do
}
progress.ExecuteMethod = this.myMethod;
Ultimately they are surprisingly similar; simply, the compiler creates the hidden method internally for the anonymous case. There is no specific performance difference, although there are cases when it might choose to create a static method (if it doesn't use this or any captured variables) - that may help marginally (but not enough to get excited about)
I would use an anonymous method when:
it is short and is logically related to the code that inits the anonymous method
it perhaps uses additional context (captured variables) that are tricky to pass into myMethod
The main thing to watch is the notorious foreach (typically) captured variable gotcha, but in some cases it is also possible to bleed a reference into the anonymous method, extending the life-time of a big object unexpectedly.
For longer work, I would use the myMethod apprach.
The performance is identical. An anonymous delegate is converted by the compiler into a regular method like any other. If you ILDSM the code you'll see that a real (but hidden) name is generated for the anonymous method.
Related
I have implemented a compiler and virtual machine for a language. The implementation is in C# and the stack-based VM uses reflection to make function calls on a set of built-ins.
Much of the code involves simply pushing and popping stack values, but the workhorse is the function call. Currently the implementation of a function call looks like this:
var calli = gencode[pc++] as CallInfo;
var calla = PopStackList(calli.NumArgs).ToArray();
var ret = calli.MethodInfo.Invoke(instance, calla);
if (ret != null) PushStack(ret);
All data items passed and returned are objects using a custom type system (no native types used). Clarification: this is an instance method, not static.
Performance testing suggests that this MethodInfo.Invoke is quite slow. The question is how to make function calls at the highest possible speed, presumably by doing more preparatory work in the compiler and generating better code.
In response to suggestions, one possibility is to create a delegate. Unfortunately as far as I can tell a delegate has to be bound to a specific instance of a class, or to a static method, and creating a delegate after creating the instance rather defeats the purpose.
I see a vote to close, but to my eye the question is not broad at all. How should a compiler implement functions calls on instance methods in a virtual machine for best performance, at the very least faster than MethodInfo.Invoke()?
Well, if you’re sure your main problem is MethodInfo.Invoke…
Use stuff from System.Linq.Expressions (Expression.Call, Expression.Parameter) to create an expression that calls that MethodInfo method, passing your parameters for instance + arguments.
Compile that expression into Action<tInstance, tArgs[]> (don't know your types of these).
Cache that Action in your CallInfo class instance.
Invoke that action as needed.
How to convert MethodInfo.Invoke to delegate:
Normally when you’re calling methods with reflection, you call MethodInfo.Invoke. Unfortunately, this proves to be quite slow. If you know the signature of the method at compile-time, you can convert the method into a delegate with that signature using Delegate.CreateDelegate(Type, object, MethodInfo). You simply pass in the delegate type you want to create an instance of, the target of the call (i.e. what the method will be called on), and the method you want to call. It would be nice if there were a generic version of this call to avoid casting the result, but never mind. Here’s a complete example demonstrating how it works:
using System;
using System.Reflection;
public class Test
{
static void Main()
{
MethodInfo method = (string).GetMethod(“IndexOf”, new Type[]{typeof(char)});
Func<char, int> converted = (Func<char, int>)
Delegate.CreateDelegate(typeof(Func<char, int>), “Hello”, method);
Console.WriteLine(converted(‘l’));
Console.WriteLine(converted(‘o’));
Console.WriteLine(converted(‘x’));
}
}
This prints out 2, 4, and -1; exactly what we’d get if we’d called "Hello".IndexOf(...) directly. Now let’s see what the speed differences are…
We’re mostly interested in the time taken to go from the main calling code to the method being called, whether that’s with a direct method call, MethodInfo.Invoke or the delegate. To make IndexOf itself take as little time as possible, I tested it by passing in ‘H’ so it would return 0 immediately. As normal, the test was rough and ready, but here are the results:
Invocation type Stopwatch ticks per invocation
Direct 0.18
Reflection 120
Delegate 0.20
Copied from: https://blogs.msmvps.com/jonskeet/2008/08/09/making-reflection-fly-and-exploring-delegates/
According to the MSDN documentation, it says it's useful for following purposes in addition to others which are understandable:
A class may need more than one implementation of the method.
It is desirable to encapsulate a static method.
Can someone help me understand these usages with an example?
A delegate is a reference to a method that you can pass around as an object.
Imagine how useful it could be to have a method that allows its callers to provide part of its own logic. Every caller can have their own method, create a delegate (reference) to their method, and pass it to the method as a parameter. As long as the main method knows what arguments to pass in (if any), it can invoke the method by its reference (delegate).
Here's a simple example, specifically of usage #1 in your question:
void RemoveItem(string item, Action preRemoveLogic)
{
preRemoveLogic(); //we don't know what method this actually points to,
//but we can still call it.
//remove the item
}
void MyCustomLogic()
{
//do something cool
}
/* snip */
RemoveItem("the item", new Action(MyCustomLogic));
//I can pass a reference to a method! Neat!
Delegates are also very important for making events work in .NET.
I am trying to learn the anonymous method and tried out this sample.
So, whenever I am trying to call WriteLog function i can just use
()=> { return "someLogData" };
The advantage is that, I need not have a separate function and can save lines of code.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
But, the same does not work out with functions like
Console.WriteLine( ()=> {return "someString" } );
Why does .NET provide this anonymous method functionality but does not let to use it in one of its own kind?
There are no overloads of Console.WriteLine which accept a Func<string> - and indeed even your current WriteLog method won't do anything useful (as you'd need to invoke the delegate).
Where methods accepting specific delegates do exist - most prominently in LINQ, but elsewhere too - you can indeed use lambda expressions or anonymous methods to invoke them.
You can call Console.WriteLine using a lambda expression, but you need to cast it to a specific delegate type - as there are only conversions from lambda expressions to specific delegate or expression types, not just Delegate or object. So this will work:
Console.WriteLine((Func<string>)(() => "someLogData"));
Again though, it wouldn't be useful to do so anyway - you don't want to log the delegate, you want to log the result of invoking the delegate.
It doesn't make very much sense for Console.WriteLine to accept delegates IMO, but it would make more sense for more flexible logging, where you don't want to evaluate the string unless you're actually going to write it to a log.
Note that your WriteLog call itself can be simpler too:
WriteLog(() => "someLogData");
You need to have your anonymous method executed to get the string.
public void WriteLog(Func<string> s)
{
Console.WriteLine(s());
}
There is an advantage in this form:
public void WriteLog(Func<string> s)
{
Console.WriteLine(s);
}
let's imagine that inside it it's written as:
public void WriteLog(Func<string> s)
{
if (needToWriteLog)
{
Console.WriteLine(s);
}
}
now, let's say that you call it this way:
WriteLog(() => StringThatNeedsFiveSecondsToBuild())
and let's compare it to a similar WriteLog that only accepts a string as a parameter:
WriteLog(StringThatNeedsFiveSecondsToBuild())
The second WriteLog will always spend 5 seconds to build the string, even when needToWriteLog is false, while the first one will build it only if it's true.
Now, compare it to Console.WriteLine: Console.WriteLine will always print its content, so there is no need to use a delegate, because the 5 seconds will always be spent.
There are some methods that are similar in C#, the ones of the family Debug.* and Trace.*, but they are different. You use them like this:
Debug.WriteLine(StringThatNeedsFiveSecondsToBuild())
the trick is that they are defined like this:
[ConditionalAttribute("DEBUG")]
public static void WriteLine(string value)
so that if the DEBUG isn't defined, the whole Debug.WriteLine(StringThatNeedsFiveSecondsToBuild()) is removed, even if it had some side effects (like spending 5 seconds :-) )
All of this show something else: it's VERY important that the delegates you pass to your WriteLog AND the parameters you pass to the Debug.* and Assert.* be side effect free (clearly ignoring the time as a side effect, I mean "real" side effects like changing variable values), because you don't know if they'll really be executed.
I'm posting it here and not code review because I want to know if the executing program can behave differently because of this (possibly something subtle).
Is a private method:
private int Foo()
{
return Bar().Bat();
}
Any different from a private Func?
private Func<int> Foo = () => Bar().Bat();
The only reason I'm doing it is to make the code more compact.
There is not much difference, but
you define templated type int (possibly type safe, even if it's not visible in current code provided)
you can use that function like a parameter to pass to another function, that you can do in the firts case too, naturally, but in first case you would need to declare a delegate type.
third is more compact, but the first is more readable, imo, so if you do not need some "functional" stuff, I would go for the first choice.
Funcs are delegates and encapsulates any methods that has equal signatur og Func. for layering I recomment that you use Private Methods
With the Func, you are actually saving a reference to an anonymous method. The compiler creates a named method out of it, and what you're doing is like saving an extra reference to it.
That being not too big of a deal, there isn't much of a difference, except the standard is naming the method. It is also more logical and readable.
I am using multithreading in my C# code as follow:
Thread startThread;
public void NewThread()
{
ThreadStart starter = delegate { foo(); };
startThread = new Thread(starter);
startThread.Start();
}
private void foo()
{
//do some work
}
And then in my application I call NewThread()to run the new thread.
But now I am having lots of threads on each class and each one has a NewThread() for itself, I was thinking of moving this to a static Util class and pass it the function name each time I want a new thread on that function.
Do you know how this the best way of doing it, if yes how can I pass the function name as a parameter to it?
Well, since the method is private, does it make sense for the caller to know the method name? If it was public, you could pass the method in:
public void NewThread(Action task)
{
ThreadStart starter = delegate { task(); };
startThread = new Thread(starter);
startThread.Name = task.Method.Name;
startSpoolerThread.Start();
}
public void foo()
{
//do some work
}
NewThread(obj.foo);
However, for a private method, I suspect an enum/switch is the best option...
NewThread(TasktType.Foo);
Alternatively, you can get the method via reflection...
public void NewThread(string name)
{
MethodInfo method = GetType().GetMethod(name,
BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic,
null, Type.EmptyTypes, null);
ThreadStart starter = delegate { method.Invoke(this, null); };
// etc (note: no point using Delegate.CreateDelegate for a 1-call usage
Unless there's a specific reason you're explicitly creating threads, why not use the Threadpool? The Threadpool.QueueUserWorkItem method takes a delegate as the unit of work to perform. The delegate is a specific type but you can wrap your own delegate call within it as you do in your example. Unless you need fine control or cancellation, in general it's better to use the thread pool rather than spinning up threads yourself.
I'd encourage you to also consider looking at the CTP of Parallel Extensions Task APIs; you don't mention why you need a thread, but they've automated much of this here's a link to their blog
Take a look at the following article on Codeproject "Poor Man's Parallel.ForEach Iterator". I think that's exactly what you are searching for. Very easy to use.
For something more powerful also take a look at Power Threading Library.
Alternatively, if you are doing a Win.Forms or similar GUI-based application I'd recommend using BackgroundWorker. It takes care of marshalling for most thread-related events for you and is also much less complex to abort (if that is something you need to do).
Delegates already provide a method to execute them asynchronously. For example:
delegate void dowork();
private static void WorkDone(IAsyncResult result)
{
((dowork)result.AsyncState).EndInvoke(result);
// this function is called when the delegate completes
}
public void Start()
{
dowork dw = delegate {// code in this block has it's own thread };
dw.BeginInvoke(WorkDone, null);
}
So in order to pass a function pointer to anything else, you need only create a delegate with the correct signature (in this case I used an anonymous method, but you can use any function with the correct signature) and call it's BeginInvoke method, passing a function that will get called when it's done.. that function has to then call EndInvoke on the original delegate, which is passed to the WorkDone function in the result parameter.