i found this syntax from another article(C# How to stop animated gif from continually looping) but it seems i cant understand it. what is the meaning or purpose of s and e from
System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));
// start
System.Drawing.ImageAnimator.Animate(txImage.Image, (s,e) => OnFrameChanged(s,e));
// stop
System.Drawing.ImageAnimator.StopAnimate(txImage.Image, (s, e) => OnFrameChanged(s, e));
private void OnFrameChanged(object sender, EventArgs e)
{
// frame change
}
or simply can anyone explain this briefly. sorry for being stupid but im really new to programming but i really want to learn thank you
There are three basic ways in which you can write an event handler. Unfortunately the author of that code got it pretty wrong by inappropriately mixing them up. What he should have used is the original C# version 1 way:
ImageAnimator.Animate(txImage.Image, OnFrameChanged);
Which is quite straight-forward and easy to understand. Certainly the syntax you should strongly prefer in this case, it makes it very easy to call the StopAnimate() method. To answer your question, I need to show the other two ways, the ones you should not use. In C# version 2, an anonymous delegate can be used to write the code for the event handler in-place:
ImageAnimator.Animate(txImage.Image, delegate {
// Put the OnFrameChanged code here...
});
In C# version 3, lambda expressions became available to write an event handler in-place:
ImageAnimator.Animate(txImage.Image, (s, e) => {
// Put the OnFrameChanged code here...
});
Which is what you asked about. The (s, e) part of the lambda expression represent the two arguments that are passed to the event handler, s is the sender, e is the EventArgs object. Do note that you don't actually use those two arguments in your OnFrameChange code so the lambda syntax is superfluous, the anonymous delegate works just as well. Albeit that many C# programmers have stopped using them and prefer to use the lambda expression syntax everywhere. Which is fair. Even though you don't use the arguments, you must still write them to convince the compiler that your lambda is a proper substitute for the delegate. Much like you still had to write OnFrameChanged with two arguments to keep the compiler happy.
Understanding lambda expression syntax can be a bit of a speed-bump, any decent introductory book about the C# language will do a better job than I can do to explain it.
Last but not least, you'll find some hackorama code in this answer to show you how to pause an animation in a PictureBox without having to use the ImageAnimator class at all. Albeit with some odds that this just adds more questions :)
Animate and StopAnimate expect "an eventHandler object that specifies the method that is called when the animation frame changes."
You can read this as
System.Drawing.ImageAnimator.Animate(txImage.Image, new EventHandler(this.OnFrameChanged))
Related
I was looking for a way to convert vb event handling to c# since i am implementing something and, after reading this post ( How do I Convert from Anonymous Event Handlers in C# to VB.Net), i tried to copy the lambda structure, and somehow it worked, but i have NO IDEA. How it does, can someonoe please explain it to me?
Or at least guide me to a link for a tutorial or something that helps me understand whats going on in here...
I mean, i can get out with this since it, somehow, worked, but i want to understand whats going on rather than just, "get the job done".
Class.Event += Class.Delegate((sometext)) => {eventhandlemethod(sometext);});
eventhandlemethod(string s)
{
MessageBox.Show(s);
}
Thanks in advance!
I am not familiar with VB.NET but an anonymous Function or Action as it would be in the case of an Eventhandler is basically just a short form of writing.
But what is the line
Class.Event += Class.Delegate((sometext) => {eventhandlemethod(sometext);});
telling you?
You have an Event, and you add the handler (obviously).
You have added an anonymous method as Eventhandler and created a Delegate from it.
Class.Delegate(<anoymous method, matching the siganture of the handler>);
Your anonymous method looks like this
(sometext) => {eventhandlemethod(sometext);}
This anonymous method (short lamba) consists of two parts
siganture => body
In Your case the signature gets eh "sometext". Derived from the rest of your code, this seems to be a string. And since eventhandlers always have void as return value, your method, would you have written a normal method, would look like this:
private void (string sometext)
{
}
which is basically, what your eventhandlemethod looks like. You could write this lambda like this as well.
(string sometext) => {eventhandlemethod(sometext);}
This shows you the expected intput type. But you can ommit this usually.
So just as goodie: you could have written
with a "normal" method, since you already have it
Class.Event += Class.Delegate(eventhandlemethod);
with a lambda
Class.Event += Class.Delegate(sometext => MessageBox.Show(sometext));
if you have multiple input variables, put them in brackets
(string s, int i, bool b) => Console.WriteLine($"{s}:{i}:{b}");
and of course, you can ommit the types as well leaving you:
(s, i, b) => Console.WriteLine($"{s}:{i}:{b}");
I hope i could clarify it a bit for you.
In assigning event handlers to something like a context MenuItem, for instance, there are two acceptable syntaxes:
MenuItem item = new MenuItem("Open Image", btnOpenImage_Click);
...and...
MenuItem item = new MenuItem("Open Image", new EventHandler(btnOpenImage_Click));
I also note that the same appears to apply to this:
listView.ItemClick += listView_ItemClick;
...and...
listView.ItemClick += new ItemClickEventHandler(listView_ItemClick);
Is there any particular advantage for the second (explicit) over the first? Or is this more of a stylistic question?
In C# 1.0 you had no choice but to explicitly define the delegate type and the target.
Since C# 2.0 the compiler allows you to express yourself in a more succinct manner by means of an implicit conversion from a method group to a compatible delegate type. It's really just syntactic sugar.
Sometimes you have no choice but to use the long-winded syntax if the correct overload cannot be resolved from the method group due to an ambiguity.
It's syntax for older version of C# compiler (<=1.1). Not needed anymore. Current compilers are sophisticated enough to get it right.
There's one (little) benefit, sometimes. If you assign event handlers by "+=", the Intellisense autocomplete feature may make writing code a bit faster.
The only time when this is useful is if it would otherwise be ambiguous - for example, if it was MenuItem(string, Delegate) - of if there were multiple equally matching overloads that would match the signature. This also includes var syntax (shown below) and generic type inference (not shown):
EventHandler handler = SomeMethod; // fine
EventHandler handler = new EventHandler(SomeMethod); // fine
var handler = new EventHandler(SomeMethod); // fine
var handler = (EventHandler)SomeMethod; // fine
var handler = SomeMethod; // not fine
In all other cases, it is redundant and is unnecessary in any compiler from 2.0 onwards.
Related to your edit - The adding of handlers isn't really affected by using new or not but there's a slight difference in removing handlers like this
listView.ItemClick -= listView_ItemClick;
and
listView.ItemClick -= new ItemClickEventHandler(listView_ItemClick);
albeit unlikely to affect most scenarios. The first version, without the new keyword, is supposedly more efficient.
There's a detailed explanation in this post but the conclusion is
So both works but which one should we use? If the events are
subscribed/unsubscribed once at the beginning/end like in a typical
WinForm application then it hardly matters. However if this is done
multiple times then the second approach is preferable as it does less
of costly heap allocations and will work faster
(second approach in that post being the one without the new keyword)
Having said that it seems like a micro optimization to me so it's unlikely to be a bottleneck in the majority of cases.
Edit:
I would be greatful if an experienced programmer with the ability to verify this sort of thing showed me the proof that this method is safe from memory leaks. I've been introducing it to many of my coding efforts but I still have a small doubt in my mind. Unfortunately I'm not good enough / don't know the tools to investigate it.
Original:
I learned recently that some uses of lambda expressions can create memory leaks:
ProjectData Project;
void OnLaunchNewProject()
{
NewProjectUI newProjectUI = new NewProjectUI();
newProjectUI.OnCompleted += (o, e) =>
{
Project = newProjectUI.NewProject;
view.Content = string.Format("Project {0} was created and saved successfully.", Project.Name);
};
newProjectUI.OnCancelled += (o, e) => { view.Content = "Operation was cancelled.";};
view.Content = newProjectUI;
}
I learned the bad impact of this method in this blog.
I do not fully understand the impact of referencing local variables in lambda expressions and this limits my ability to circumvent the problem.
Between the typical approach and the use of lambda, what's the ideal compromise? The thing I like about lambda is skipping the definition of the EventHandler's arguments in the body of my class (the sender/routed args) when I don't need them.
Unfortunately, the blog post you mentioned is wrong. There is not general issue with memory leaks in lambda expressions. In the blog examples, the finalizers are never called because the author never removes the anonymous methods from the event. So the .NET runtime thinks that the method still might be called later and cannot remove the class from memory.
In your code, you will release the NewProjectUI instance somewhere, and this is the point where all events become unsued and when the assigned lambda method also becomes unused. Then the GC can remove the anonymous lambda-helper-class and free the used memory.
So, again: There is no issue in .NET when using local variables in lambda expressions.
But to make your code better, move the code from the lambda expressions to named methods and add these methods to the events. This also makes it possible to remove the methods from the events when they're no longer needed.
When I deal set up events, I usually write as such:
data.event += new data.returndataeventhandler(method);
And have a method as such:
void method(parameter)
{
dosomething();
}
This is when the event returns an object.
I have just been reading through somebody elses code and they have used, what seems to be a much cleaner way, as such:
data.ReturnData += delegate(DataSet returnedDataSet)
{
dataset = returnedDataSet;
};
Is there any downfall to this way?
Thanks.
The one major downfall of using anonymous delegates (or the even-cleaner Lambda as suggested by tster) is that you're not going to be able to unsubscribe it from the event later unless you give it some sort of name.
In most cases, this is "No Big Deal (tm)" because the delegate will go away whenever the event source goes away, but this can be a "Subtle Mistake (tm)" if you're subscribing to static events or events on long-lived objects (e.g., the WPF Dispatcher object).
In your case, this doesn't look like a problem at all, so I'd definitely recommend going with tster's recommendation (assuming you're using an appropriately recent version of .Net):
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
(The compiler can infer the type of returnedDataSet from the EventHandler type of ReturnData.)
The primary downfall of using anonymous delegates is that they are not reusable. Other than that there is typically no difference between defining a delegate and then using it elsewhere in your code versus using an anonymous delegate.
One down fall is that it will not appear in your method drop down list. If you do it inline, it should only be simple, nothing overly complex.
Like said by others, the most obvious is not reusable.
Other points:
readability in particular if you have large method body
because .NET generate a random name for anonymous method (not very meaningful or readable) if you use reflection type technology or profiler, it may complicate traceability.
The only downfall is that if you have more than one event it's easier to point it to a method. If you had to attach events in different blocks to the same handler, you would have to store your delegate somewhere so that both blocks could "see" it.
Even cleaner:
data.ReturnData += returnedDataSet => dataset = returnedDataSet;
Nope its just anonymous method thats all.
You can read more about anonymous methods here.
Aside from the other answers of reusablity/Intellisense, I believe the only downfall is if you need to remove the handler later. With a delegate/lamba you cannot easily remove your handler if it no longer needs to be called.
After discovering lambda expressions, and their use as anonymous functions, I've found myself writing a lot of more trivial events such as these:
txtLogin.GotFocus += (o, e) =>
{
txtLogin.Text = string.Empty;
txtLogin.ForeColor = SystemColors.ControlText;
};
txtLogin.LostFocus += (o, e) =>
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
I've also moved away from event handlers which just call other functions, replacing them with small lambdas which do the same:
backgroundWorker.DoWork += (o, e) => DatabaseLookup.Open(e.Argument as string);
I've found some similar questions addressing performance concerns and pointing out that you can't remove them, but I haven't found any addressing the simple question of is this a good idea?
Is the use of lambdas in such a way considered good form, or do more experience programmers look down on this? Does it hide event handlers in hard-to-find places, or does it do the code a service by reducing the number of trivial event handlers?
It's a perfectly reasonable idea - but in this particular case, I would use an anonymous method instead:
txtLogin.LostFocus += delegate
{
txtLogin.Text = "Login...";
txtLogin.ForeColor = SystemColors.InactiveCaptionText;
};
The benefit is that you don't have to specify the parameters - which makes it clearer that you're not using them. This is the only advantage that anonymous methods have over lambda expressions.
The performance hit is almost always going to be negligible. The inability to remove them afterwards is a very real problem if you do need to be able to remove the handler, but I find that often I don't. (Reactive Extensions has a nice approach to this - when you subscribe to an observable sequence, you're given back an IDisposable which will remove the subscription if you call it. Very neat.)
Actually, it's consider it putting event handlers in easy-to-find places, namely right next to the name of the event it's assigned to.
A lot of the time, you'll see event handlers like:
void Text1_KeyDown(....) {....}
attached to the KeyUp event of txtFirstName, because after using Intellisense to create the handler, someone decided to rename the textbox, and that KeyUp worked better. With the Lambda, the object, the event and the function are all together.
It's a tricky one. I remember reading in Code Complete about how some (smart) people say you should keep the flow of control as simple as possible, with many arguing for single entry and exit points from a method, because not doing so made the program harder to follow.
Lambdas are getting even further away from that, making it very difficult in some cases to follow what's happening, with control leaping around from place to place.
Basically, I think it probably is a bad idea because of this, but it's also powerful and makes life easier. I certainly use them a fair amount. In summary, use with caution!