Reading Output From Process And Process Issues?

  • (2 Pages)
  • +
  • 1
  • 2

19 Replies - 1517 Views - Last Post: 11 December 2012 - 06:38 PM Rate Topic: -----

#16 adn258  Icon User is offline

  • D.I.C Addict

Reputation: 11
  • View blog
  • Posts: 753
  • Joined: 31-August 11

Re: Reading Output From Process And Process Issues?

Posted 09 December 2012 - 08:27 PM

View PostCodingSup3rnatur@l-360, on 09 December 2012 - 05:01 PM, said:

Using statements have nothing to do with event subscriptions. If you didn't use the using statement, as so:

Spoiler


the result, in terms of the event subscription, would be exactly the same, because the ffmpegproc object will still fall out of scope, and become unreachable from your code at the end of the BtnBeginVideoConvert_Click.

A using statement ensures Dispose() is called. That's all. Further, Dispose() is totally unrelated to the event subscription you made. Finally, Dispose() usually has only, at best, an indirect effect on garbage collection.

Calling Dispose() does not cause garbage collection to occur (unless someone explicitly coded it to do so, using GC.Collect()), or magically allow the object to be garbage collected. Dispose() is actually largely unrelated to garbage collection. Dispose() is about freeing resources that the garbage collector has no knowledge of how to free (file handles, database connections etc). Remember, garbage collection deals only with raw memory.

In my opinion, you are best off separating IDisposable and garbage collection in your mind. They compliment each other as an all round means of resource management, perhaps, and therefore there is the occasional small overlap between them, but there is generally no direct relationship between the two.


Thank you so much supernatural. So what you're saying is all objects get garbage collected when they go out of scope even if you don't dispose them or use using( ??

So even file browser dialogs and timers?

That said since my event has nothing to do with this garbage collection I still am not seeing why I shouldn't unsubscribe it at the end? Sorry supernatural. You've been an amazing help by the way those are really my last two questions regarding this.
Was This Post Helpful? 0
  • +
  • -

#17 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 982
  • View blog
  • Posts: 969
  • Joined: 30-September 10

Re: Reading Output From Process And Process Issues?

Posted 10 December 2012 - 03:58 AM

Quote

So what you're saying is all objects get garbage collected when they go out of scope even if you don't dispose them or use using( ??


Yes. An object will become eligible for garbage collection when it goes out of scope, and is no longer reachable by your code. Nothing to do with Dispose() at all.

Quote

So even file browser dialogs and timers?


Absolutely. They will happily be garbage collected if they become unreachable from your code, even if you haven't called Dispose(). On the flip side, if you do call Dispose(), but you keep a reference to your object so you can reach it, the object will NOT be garbage collected. As I said, there is no direct relationship between calling Dispose() and garbage collection. Whether an object is garbage collected or not depends on the references there are to an object, not whether you call Dispose() or not.

Typically, in objects that have a Dispose() method, one of two things will happen if the object is garbage collected when you haven't called Dispose() on the object, depending on whether the object has defined a finalizer or not:

If the object does define a finalizer:

The object will be garbage collected, but before its memory is reclaimed by the garbage collector, it's finalizer will be called. If the finalizer has been well written, it will call Dispose(false) on the object to clean up unmanaged resources that the garbage collector can't clean up. The object's memory will then be reclaimed.

If the object does NOT define a finalizer:

The object will be garbage collected, and its memory will be reclaimed. End of story. No external resources will be freed, because the garbage collector has no knowledge of such resources. This means any external resources used by the object will remain allocated.


Neither of those cases are particularly good.

The first one at least means the allocated unmanaged resources will be released before the object's memory is reclaimed by the garbage collector, but it is not advisable to rely on the finalizer to clean things up for you, for all the reasons I outlined here, plus many objects that implement IDisposable don't define a finalizer anyway.

The second one means you definitely leak resources if the object held such resources before it was garbage collected. The end.

Quote

since my event has nothing to do with this garbage collection I still am not seeing why I shouldn't unsubscribe it at the end? Sorry supernatural


It's okay. I'll explain it to you all day if I have to :)/> What exactly is it that you aren't understanding?

Firstly, it's definitely not that you shouldn't unsubscribe the event in this case (if it gives you peace of mind, you should absolutely do so). Some people would argue that you should unsubscribe out of good habit, as, let's face it, it's no hardship to do so in this case. However, the point is that it won't cause any problems if you don't unsubscribe (for whatever reason), in this case.


The potential problems that can arise if you do not unsubscribe from events are problems with garbage collection alone. They are nothing to do with IDisposable.

I'll show you an example of where not unsubscribing would cause a 'memory leak'.

In this example, I have two forms, Form1 and Form2. The user can open Form2 whenever they like by clicking a button called btnOpen. Each time an object of Form2 is constructed, it subscribes to an event on a global instance of a class called EventPublisher

Form1

Spoiler


Form2

Spoiler


EventPublisher

Spoiler


So, every time the user opens the second form, a new instance of it is created, and when they close the form, the form is disposed via the using statement I have used. The form instance then promptly falls out of scope. Now, at this point, you cannot access that form instance. It is out of your reach, and is no longer of any use to you. Therefore, it should be eligible for garbage collection. However, it isn't eligible for garbage collection because of the event it subscribed to in its constructor.

The act of subscribing to that event added a reference to the Form2 instance to the EventPublisher instance. Therefore, even though I'm calling Dispose() on the Form2 instances, and the instances are falling out of scope, because the EventPublisher instance is holding references to my Form2 instances, those instances will not be garbage collected, hence you have a 'memory leak'.


Now look at this slightly modified version of the above example:

Form1 remains unchanged.

Form2

Spoiler


EventPublisher

Spoiler



Now, with this modified example, there is no problem with the event subscriptions leaking memory by preventing Form2 instances from being garbage collected. This is because, this time, when the user closes the second form, the Form2 instance falls out of scope, just as before. The difference this time however, is that the EventPublisher instance(s) used in Form2 have also fallen out of scope by that point, where as with the first example, the single EventPublisher instance never fell out of scope, and was always reachable by my code.

So, in this modified example, the EventPublisher instances will be garbage collected, thus releasing the references held due to the event subscriptions, thus allowing the Form2 instances to be garbage collected also. Therefore, the Form2 instances are not being kept in memory unnecessarily, and there is therefore no 'memory leak', and no problem.

This post has been edited by CodingSup3rnatur@l-360: 12 January 2014 - 02:18 PM
Reason for edit:: Grammar

Was This Post Helpful? 2
  • +
  • -

#18 adn258  Icon User is offline

  • D.I.C Addict

Reputation: 11
  • View blog
  • Posts: 753
  • Joined: 31-August 11

Re: Reading Output From Process And Process Issues?

Posted 10 December 2012 - 05:22 AM

I think I'm getting this down better. So basically the event always had reference in your code so it couldn't be garbage collected and I get the difference now between garbage collection and dispose. dispose just makes it eligible for GC.

So the reason that event handler never went out of scope is because you set the EvenPublisher to static readonly am I accurate?

An old program of mind had this so correct me if I'm wrong this is a mistake unless you unsubscribe. I created an event which changed the color of the main forum call it form1 by opening up a color change dialog in form2. When the user clicked the color he or she wanted this would change the main forums color via and event here it goes

 private void colorsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Color_Selector_Look cs = new Color_Selector_Look(false);
            cs.ColorUpdated += new EventHandler<Color_Selector_Look.ColorUpdatedEventArgs>(cs_ColorUpdated);
            cs.ShowDialog();   
        }



Then in form2 the user had two options using this same dialog for an event to change font color or the actual windows color itself


 public partial class Form2: Form
    {
        //event and objects used for color change
        public class ColorUpdatedEventArgs : EventArgs
        {
            public ushort Choice { get; set; }
            public Color Cname { get; set; }
        }

        public event EventHandler<ColorUpdatedEventArgs> ColorUpdated;
        protected virtual void OnColorUpdated(ColorUpdatedEventArgs e)
        {
            if (ColorUpdated != null)
                ColorUpdated(this, e);
        }

 public Form2(bool textcolor)
        {
            InitializeComponent();
            //whether or not we are changing text color or background color
            if (textcolor == true)
            {
                foreach (Control c in this.Controls)
                {
                    if (c is Button)
                    {
                        c.Enabled = false;
                        c.Visible = false;
                    }
                }
                this.pctr_box_colorwheel.Click += new EventHandler(pctr_box_colorwheel_Click_FontColor);
                this.lbl_current_operations.Text = "Click On Color Wheel To Select Font Color:";
            }
            else
            {
                this.pctr_box_colorwheel.Click += new EventHandler(pctr_box_colorwheel_Click);
            }
            
        }


My assumption is the above events wouldn't case a problem since they do go out of scope. The top is the event used for our colorevent and this happens when a user clicks a color on the wheel

private void pctr_box_colorwheel_Click(object sender, EventArgs e)
        {
            if (!(usColorChoice == 0))
            {
                ColorUpdatedEventArgs c = new ColorUpdatedEventArgs();
                c.Choice = usColorChoice;
                c.Cname = pctrbox_sample.BackColor;
                OnColorUpdated(c);
            }
            else
            {
                MessageBox.Show("You Must Select An Object To Set Color Too From The Left", "No Object Set To Change Color Too", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            
            
        }




So basically this form2 though would never get disposed correct UNLESS in form1 I used

 private void colorsToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Color_Selector_Look cs = new Color_Selector_Look(false);
            cs.ColorUpdated += new EventHandler<Color_Selector_Look.ColorUpdatedEventArgs>(cs_ColorUpdated);
            cs.ShowDialog(); 
            cs.ColorUpdated -= new EventHandler<Color_Selector_Look.ColorUpdatedEventArgs>(cs_ColorUpdated);
  

        }



So after the dialog was closed it would unsubscribe the event. Is my thinking right now? Thanks again supernatural.

This post has been edited by adn258: 10 December 2012 - 05:43 AM

Was This Post Helpful? 0
  • +
  • -

#19 CodingSup3rnatur@l-360  Icon User is offline

  • D.I.C Addict
  • member icon

Reputation: 982
  • View blog
  • Posts: 969
  • Joined: 30-September 10

Re: Reading Output From Process And Process Issues?

Posted 10 December 2012 - 06:56 AM

Quote

dispose just makes it eligible for GC


No. Dispose() doesn't automatically make the object eligible for garbage collection. If I have this:

public class Test {
    private StreamWriter writer;

    public Test() {
        writer = new StreamWriter("Test.txt"); 
        writer.Dispose();
    }

}



The fact that I called Dispose() on writer does not, in any way, make it eligible for garbage collection. The object referenced by writer will only be eligible for garbage collection when it becomes unreachable. Calling Dispose() does NOT make it unreachable. I can still reference the object through the reference held in writer, for example.

Quote

So the reason that event handler never went out of scope is because you set the EvenPublisher to static readonly am I accurate?


Yes. The static readonly meant there was always a rooted reference to the same EventPublisher instance, so it never became eligible for garbage collection.

Quote

My assumption is the above events (the picture box .Click event) wouldn't case a problem since they do go out of scope.


Correct conclusion; not sure if you have the correct reasoning. It wouldn't cause a problem. Yes, the picture box would contain a reference to form 2 as a result of the event subscription. However, the picture box isn't preventing the form from being garbage collected when the form falls out of scope and becomes unreachable, because if the form becomes unreachable, the picture box will also become unreachable, as it is part of the form. Therefore, both will become eligible for garbage collection, and there is no problem.


Quote

So basically this form2 though would never get disposed correct UNLESS in form1 I used


Form2 would never get disposed, because you aren't calling Dispose() on it. It's as simple as that. When an object is garbage collected, we don't say it's been disposed, we say the object has been garbage collected, or the object has had its memory reclaimed.

As far as the ColorUpdated event subscription is concerned, the fact that you don't unsubscribe isn't causing a problem there either. This line:

cs.ColorUpdated += new EventHandler<Color_Selector_Look.ColorUpdatedEventArgs>(cs_ColorUpdated);


is adding a reference to form 1 in form 2 (cs). Therefore, if there was a problem here, it would be that that reference was preventing the form 1 instance (NOT form 2) from being garbage collected when it should be.

However, as the form object referenced by cs falls out of scope, and becomes unreachable at the end of the colorsToolStripMenuItem_Click method, it will become eligible for garbage collection. Therefore, it will be garbage collected, thus destroying the reference to form 1 held by the form 2, therefore meaning form 2 won't prevent the form 1 instance from being garbage collected when it should be, and therefore, there is no problem.

This post has been edited by CodingSup3rnatur@l-360: 10 December 2012 - 07:23 AM

Was This Post Helpful? 1
  • +
  • -

#20 adn258  Icon User is offline

  • D.I.C Addict

Reputation: 11
  • View blog
  • Posts: 753
  • Joined: 31-August 11

Re: Reading Output From Process And Process Issues?

Posted 11 December 2012 - 06:38 PM

Thanks so much again supernatural. It's also good to know that unsubscribing my event in that code wouldn't be necessary and that I was doing things RIGHT but better yet now I know why I was doing things right.
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2