How can i get the outlook search folder deleted event? - c#

I need to get an event when delete outlook search folder
current i am using below event but its not fire
void folders_FolderRemove()
{
MessageBox.Show("A folder was removed");
}

It is not clear how you subscribe to the Remove event of the Folders class.
Most probably the source object is swiped by the garbage collector. You need to declare it at the global scope (i.e. class level) to make sure it is alive when the folder is removed.

Related

Does not removing event Handlers cause problems in .Net?

I have the following code:
public void LoadPage()
{
LayoutPanel.Controls.Clear();
ContentObjects = LoadContentObjects();
foreach (string img in ContentObjects)
{
thumbnail = new ctrlThumbnailControl(img);
LayoutPanel.Controls.Add(thumbnail);
thumbnail.ThumbnailSelected += Thumbnail_ThumbnailSelected;
}
}
private void Thumbnail_ThumbnailSelected(string PathToMedia)
{
lblFileName.Text = PathToMedia;
}
I create a thumbnail control for each image loaded (limited to 150 per page). The thumbnail controller has an event which is raised on hovering over the control.
So this page has 150 controls with events. When I load the next page I do not remove the events. I do remove the controls. And create another 150 controls adding events to them.
So the question is:
Are the event handlers removed when the controls are Clear()ed?
if not how would I programmatically clear the event handlers without going through each control individually and removing it's handler?
What you're doing is safe because the thing you're throwing away is the thing that holds the reference. That is, each Control is holding a reference to a delegate which holds a reference to the object with the event handler, which is typically a Form or some other long-lived object, but the object with the event handler holds no reference to the Control after it is removed from the UI. The Control becomes completely unreachable (assuming you're not holding a reference to it for some other purpose), so it's irrelevant that it still "knows" about the long-lived object. When the garbage collector runs, the Control will vanish and the delegate with it.
On the other hand, what you don't want to do is register a short-lived object as an event handler for a long-lived object (without remembering to unregister). When you do this, even after you think you've "removed" the short-lived object, the long-lived object still knows about the short-lived object, which keeps it alive such that it is never garbage collected and you have what is essentially a managed-memory version of a memory leak (not to mention that the now-supposedly-disconnected objects will still be responding to events).
If the controls are not visible there is no way to trigger the event from the GUI. There is no need to detach the events. They do not do any "harm".

Deleting event methods

Accidentally added some event methods in C# from the form builder. If you delete them from the .cs file it throws an error. How do I get rid of them?
There are two parts to subscribing to an event.
You have the event method itself, which you tried deleting.
You have subscriptions to the event method. You can have any number of controls subscribing to a single event method.
If you just delete the event method, then you still have controls subscribed to that event. But it no longer exists, so you get an error.
You can delete the subscription to the event from the designer by right-clicking the event in the properties window and clicking "Reset":
Or you could open the Designer.cs file and delete event subscription from there. For example:
this.richTextBox1.KeyDown += new System.Windows.Forms.KeyEventHandler(this.richTextBox1_KeyDown);
As well as deleting them from the code file, you will need to find the control that is referencing those event methods and remove the reference to the method.
You need to go to Form.Designer.cs and remove the red line which is subscription of the event handler.If you see an error screen like this:
Just click the link under the Instances of this error, and remove that line and it should be fine.
Go to the button or element that reference the Event and remove it from there, Desingn - > Right click on element -> Properties - > Events - > Remove from there what you dont need, or do it in the code, you can search in it for the name of the method you deleted.
And the next time just use Ctrl + Z.

How do I code a DataTable.RowChanged event to be attached at compile time?

I have the following setup in a Windows Forms project:
myDataGridView, whose data source is myBindingSource, whose data source is myProjectDataSet and whose data member is myDataTable, whose data is populated from a database at runtime per user request.
When the user makes a data change on myDataGridView I have the changes filtering down to update myDataTable as well. I then want to handle myDataTable's RowChanged event, but I'm not quite sure in which project file I should put the code to attach the event handler and then handle the event so that they are hooked up when the data table is "initialized". I know I can hook up the event in my Form.cs file after the form loads, but I'd prefer to hook it up in myProjectDataSet.cs if I can. But, since myProjectDataSet.cs is auto-generated, I'm not sure if this is the best place to do it.
I hope that made sense. Thanks for your input.
Thanks, realized I had to add to hook it up in my Form.Designer.cs file after myProjectDataSet instantiated.
this.myProjectDataSet.myDataTable.RowChanged += new System.Data.DataRowChangeEventHandler(myDataTable_RowChanged);
Then, of course, I handled the event in Form.cs
private void myDataTable_RowChanged(object sender, System.Data.DataRowChangeEventArgs e)
{
//Do stuff.
}
But now the hook is getting wiped out when Form.Designer.cs auto-generates. Oh well I'll figure that one out too.

Should I always disconnect event handlers in the Dispose method?

I'm working in C# and my workplace has some code standards. One of them is that each event handler we connect (such as KeyDown) must be disconnected in the Dispose method. Is there any good reason for that?
Unless you expect the publisher of the event to outlive the subscriber, there's no reason to remove the event handler, no.
This is one of those topics where folk lore has grown up. You really just need to think about it in normal terms: the publisher (e.g. the button) has a reference to the subscriber. If both the publisher and the subscriber will be eligible for garbage collection at the same time anyway (as is common) or if the publisher will be eligible for garbage collection earlier, then there's no GC issue.
Static events cause a GC problem because they're effectively an infinitely-long-lived publisher - I would discourage static events entirely, where possible. (I very rarely find them useful.)
The other possible issue is if you explicitly want to stop listening for events because your object will misbehave if the event is raised (e.g. it will try to write to a closed stream). In that case, yes, you should remove the handler. That's most likely to be in the case where your class implements IDisposable already. It would be unusual - though not impossible - for it to be worth implementing IDisposable just to remove event handlers.
Well, perhaps, the standard was proposed as a defensive practice against memory leaks. I can't say, this is a bad standard. But, I personally prefer to disconnect event handler ONLY where needed. In that way, my code looks clean and less verbose.
I have written a blog explaining how event handler causes a memory leak and when to disconnect; https://www.spicelogic.com/Blog/net-event-handler-memory-leak-16. Here, I will summarize the explanation to address your core question.
C# Event Handler operator is actually a reference injector:
In C# += operator looks very innocent and many new developers do not get the idea that the right-hand side object is actually passing it's a reference to the left-hand side object.
Event publisher protects event subscriber:
So, if an object gets a reference to another object, what is the problem? The problem is that, when the garbage collector comes to clean up and find an object that is important to keep in memory, it will not clean up all objects that are also referenced by that important object. Let me make it simple. Say, you have an object named "Customer". Say, this customer object has a reference to the CustomerRepository object so that the customer object can search the repository for all of its Address objects. So, if the garbage collector finds that the customer object is needed to be alive, then the garbage collector will also keep the customer repository alive, because, the customer object has a reference to the customerRepository object. Which makes sense as the customer object needs the customeRepository object to function.
But, does an event publisher object needs an event handler to function? NO, right? the event publisher is independent of the event subscriber. Event publishers should not care if an event subscriber is alive or not. When you use the += operator to subscribe to an event of an event publisher, the event publisher receives a reference of the event subscriber. The garbage collector thinks, the event publisher needs the event subscriber object to function, so it does not collect the event subscriber object.
In that way, the event publisher object "a" protects the event subscriber object "b" from being collected by the garbage collector.
Event publisher object PROTECTS the event subscriber object as long as the event publisher object is alive.
So, if you detach the event handler, then the event publisher does not hold the reference of the event subscriber, and the garbage collector can freely collect the event subscriber.
But, do you really need to detach the event handler all the time? The answer is No. Because many event subscribers are really supposed to be living in the memory as long as the event publisher lives.
A Flow Chart to make the right decision:
Most of the time, we find the event subscriber object is as important as the event publisher object and both are supposed to be living at the same time.
Example of a scenario where you do not need to worry:
For example, a button click event of a window.
Here, the event publisher is the Button, and the event subscriber is the MainWindow. Applying that flow chart, ask a question, does the Main Window (event subscriber) supposed to be dead before the Button (event publisher)? Obviously No. Right? That won't even make sense. Then, why worry about detaching the click event handler?
An example when an event handler detachment is a MUST:
I will provide one example where the subscriber object is supposed to be dead before the publisher object. Say, your MainWindow publishes an event named "SomethingHappened" and you show a child window from the main window by a button click. The child window subscribes to that event of the main window.
And, the child window subscribes to an event of the Main Window.
When the user clicks a button in a MainWindow, the child window shows up. Then the user closes the child window when he/she finishes the task from the child window. Now, according to the flow chart I provided if you ask a question "Does the child window (event subscriber) supposed to be dead before the event publisher (main window)? The answer should be YES. Right? Then, make sure to detach the event handler when the task of the child window is done. A good place is the Unloaded event of the ChildWindow.
Validating the concept of memory leak:
I have profiled this code using the dotMemory Memory profiler software from Jet Brains. I started the MainWindow and clicked the button 3 times, which shows a child window. So, 3 instances of the Child Window showed up. Then, I have closed all the child windows and compared a snapshot before and after the child window appearance. I found that 3 objects of the Child Window were living in the memory even I have closed all of them.
Then, I have detached the event handler in the Unloaded event of the child window, like this:
Then, I have profiled again, and this time, wow! no more memory leak caused by that event handler.
I had a major GDI leak in my application if I didn't unregister the event handlers in the Dispose() of a user control that was being dynamically created and destroyed. I found the following in the Visual Studio 2013 help, in the C# Programming Guide. Note the stuff I have put in italics:
How to: Subscribe to and Unsubscribe from Events
...snip...
Unsubscribing
To prevent your event handler from being invoked when the event is raised, unsubscribe from the event. In order to prevent resource leaks, you should unsubscribe from events before you dispose of a subscriber object. Until you unsubscribe from an event, the multicast delegate that underlies the event in the publishing object has a reference to the delegate that encapsulates the subscriber's event handler. As long as the publishing object holds that reference, garbage collection will not delete your subscriber object.
Note that in my case both the publisher and the subscriber were in the same class, and the handlers are not static.
One reason to do it I faced was that it affected assembly unloadability

C# Should I manually remove the event handler I declared?

Okay, make an example here:
I have UserControl A, UserControl B, UserControl C and one Windows Form.
This Windows Form is only started with UserControl A.
UserControl C has [Next] and [Back] buttons.
Say, UserControl A is declared with an event handler. One of function in UserControl A will actually raise the event call to execute one function at UserControl C.
So, at UserControl C, I have to add with
"UserControlA.OneFunction += this.UserControlC_Function;"
If I click Next button at UserControl C, it will dispose the UserControl A and add new UserControl B to the Windows Form. But I never remove this event handler manually.
One of the function in UserControl A is the caller (where event is declared).
One of the function in UserControl C is the listener.
So, these are my questions:
Should I manually remove the handler before UserControl A disposed?
Will this User Control A dispose automatically remove the handler that declared previously?
Should I add this somewhere?
"UserControlA.OneFunction -= this.UserControlC_Function;"
By convention, we don't. And since no event should be invoked after disposal, there is no need to do so unless the control in question is behaving weirdly.
No. At least there isn't such code as seen from reflector.
You don't need to remove the handlers in this case because neither the form nor its buttons are referenced by code external to the form, and the entire object graph will therefore be garbage collected.
The answer to this post does a really good job explaining when you need to manually remove an event handler and when it is not necessary.
Do I need to remove event subscriptions from objects before they are orphaned?
If the form is released (assuming no other objects has a reference to the objects in question) there's little risk of not removing the event handler, however it's a good idea always to remove the event handler before the object listening can no longer be reach (ie all variables referencing the object i sout of scope) not doing so can create a memory leak.
This is not the case in your situation (if I get what you are describing, code would make it more clear)
The problem would be if you attach a delegate referencing object C to an event on object A and then looses access to C (e.g. assigning a new value to the variable). C would then hang around until A is garbage collected
If the memory lifetime of an event publisher is not limited relative to the useful lifetime of an event subscriber, failure to unsubscribe an event will likely cause a memory leak. Were it not for the unfortunate hassle of doing so, there wouldn't be any reason for an event subscriber that was being disposed not to unsubscribe from all events, and for an event publisher that was being disposed not to nullify all event subscriptions. Since neither C# nor VB provides any convenient means of doing those things, however, one has to balance the hassle of proper subscription handling with the fact that in many situations one can get away skimping on it.

Categories