When is StreamWriter disposed?











up vote
1
down vote

favorite












I have a small class I threw together to implement a quick logger. I composed it with a private System.IO.StreamWriter which is instantiated in the constructor. Because the way I'm using is prevents me from implementing a using block, I added a finalizer and called the StreamWriter's Dispose() method in it. However, when executing, that finalizer throws an exception because the StreamWriter has already been disposed.




System.ObjectDisposedException - Cannot access a closed file.




I'm confused how this happened and I'm wondering if this means I don't need to worry about cleaning up the StreamWriter. Here is my class:



public class TextFileLogger : AbstractTextLogger
{
private const string LogPath = @"C:";
private const string LogFileName = "MyFile.log.txt";
private readonly StreamWriter _writer;

public TextFileLogger()
{
_writer = new StreamWriter($"{LogPath}{LogFileName}", true);
_writer.AutoFlush = true;
}

~TextFileLogger()
{
_writer.Dispose();
}

protected override void WriteLine(string line)
{
_writer.WriteLine(line);
}
}









share|improve this question


















  • 5




    You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
    – Flydog57
    Nov 21 at 20:00












  • docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
    – tkausl
    Nov 21 at 20:00










  • @Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
    – bubbleking
    Nov 21 at 21:13










  • Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
    – Flydog57
    Nov 21 at 21:17















up vote
1
down vote

favorite












I have a small class I threw together to implement a quick logger. I composed it with a private System.IO.StreamWriter which is instantiated in the constructor. Because the way I'm using is prevents me from implementing a using block, I added a finalizer and called the StreamWriter's Dispose() method in it. However, when executing, that finalizer throws an exception because the StreamWriter has already been disposed.




System.ObjectDisposedException - Cannot access a closed file.




I'm confused how this happened and I'm wondering if this means I don't need to worry about cleaning up the StreamWriter. Here is my class:



public class TextFileLogger : AbstractTextLogger
{
private const string LogPath = @"C:";
private const string LogFileName = "MyFile.log.txt";
private readonly StreamWriter _writer;

public TextFileLogger()
{
_writer = new StreamWriter($"{LogPath}{LogFileName}", true);
_writer.AutoFlush = true;
}

~TextFileLogger()
{
_writer.Dispose();
}

protected override void WriteLine(string line)
{
_writer.WriteLine(line);
}
}









share|improve this question


















  • 5




    You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
    – Flydog57
    Nov 21 at 20:00












  • docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
    – tkausl
    Nov 21 at 20:00










  • @Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
    – bubbleking
    Nov 21 at 21:13










  • Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
    – Flydog57
    Nov 21 at 21:17













up vote
1
down vote

favorite









up vote
1
down vote

favorite











I have a small class I threw together to implement a quick logger. I composed it with a private System.IO.StreamWriter which is instantiated in the constructor. Because the way I'm using is prevents me from implementing a using block, I added a finalizer and called the StreamWriter's Dispose() method in it. However, when executing, that finalizer throws an exception because the StreamWriter has already been disposed.




System.ObjectDisposedException - Cannot access a closed file.




I'm confused how this happened and I'm wondering if this means I don't need to worry about cleaning up the StreamWriter. Here is my class:



public class TextFileLogger : AbstractTextLogger
{
private const string LogPath = @"C:";
private const string LogFileName = "MyFile.log.txt";
private readonly StreamWriter _writer;

public TextFileLogger()
{
_writer = new StreamWriter($"{LogPath}{LogFileName}", true);
_writer.AutoFlush = true;
}

~TextFileLogger()
{
_writer.Dispose();
}

protected override void WriteLine(string line)
{
_writer.WriteLine(line);
}
}









share|improve this question













I have a small class I threw together to implement a quick logger. I composed it with a private System.IO.StreamWriter which is instantiated in the constructor. Because the way I'm using is prevents me from implementing a using block, I added a finalizer and called the StreamWriter's Dispose() method in it. However, when executing, that finalizer throws an exception because the StreamWriter has already been disposed.




System.ObjectDisposedException - Cannot access a closed file.




I'm confused how this happened and I'm wondering if this means I don't need to worry about cleaning up the StreamWriter. Here is my class:



public class TextFileLogger : AbstractTextLogger
{
private const string LogPath = @"C:";
private const string LogFileName = "MyFile.log.txt";
private readonly StreamWriter _writer;

public TextFileLogger()
{
_writer = new StreamWriter($"{LogPath}{LogFileName}", true);
_writer.AutoFlush = true;
}

~TextFileLogger()
{
_writer.Dispose();
}

protected override void WriteLine(string line)
{
_writer.WriteLine(line);
}
}






c# .net idisposable finalizer






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 21 at 19:55









bubbleking

1,02711127




1,02711127








  • 5




    You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
    – Flydog57
    Nov 21 at 20:00












  • docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
    – tkausl
    Nov 21 at 20:00










  • @Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
    – bubbleking
    Nov 21 at 21:13










  • Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
    – Flydog57
    Nov 21 at 21:17














  • 5




    You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
    – Flydog57
    Nov 21 at 20:00












  • docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
    – tkausl
    Nov 21 at 20:00










  • @Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
    – bubbleking
    Nov 21 at 21:13










  • Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
    – Flydog57
    Nov 21 at 21:17








5




5




You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
– Flydog57
Nov 21 at 20:00






You can't do that. Finalizers (aka destructors) run on a separate thread with no guarantees that other managed objects to which your object refer still exist. The only things you should clean up in a Finalizer are unmanaged resources. Make your TextFileLogger Disposable (implement IDisposable) and read up on the "Dispose Pattern" to get it just right. If a class has no native resources (like yours) it should not have a Finalizer
– Flydog57
Nov 21 at 20:00














docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
– tkausl
Nov 21 at 20:00




docs.microsoft.com/en-us/dotnet/standard/garbage-collection/…
– tkausl
Nov 21 at 20:00












@Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
– bubbleking
Nov 21 at 21:13




@Flydog57 - I'm familiar with implementing IDisposable, and have done so a few times before. I thought I could somehow just dispose of the StreamWriter inside my class without needing a using block. Since this is a quick and dirty, temporary thing, I will probably just need to new up the StreamWriter in every call to WriteLine so I can use it in a using block. This is awful, and will take about 14.5 times longer in execution time, according to my measurements, but for a short lived project, I'd rather take that performance hit than completely rearchitect everything.
– bubbleking
Nov 21 at 21:13












Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
– Flydog57
Nov 21 at 21:17




Add a Dispose method for the things somewhere else in your code. As long as it's in your normal code, you can dispose of it. However, once you get in Finalizer code, all the "managed code guarantees" mostly get wiped off the table. Finalizers are very easy to mess up.
– Flydog57
Nov 21 at 21:17












1 Answer
1






active

oldest

votes

















up vote
4
down vote



accepted










The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.



The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.



You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.






share|improve this answer





















  • Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
    – bubbleking
    Nov 21 at 21:05










  • Yes removing the finalizer would be the "hope for the best" option.
    – Scott Chamberlain
    Nov 22 at 0:59










  • I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
    – bubbleking
    Nov 22 at 12:23










  • Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
    – bubbleking
    Nov 22 at 12:28










  • I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
    – Scott Chamberlain
    Nov 22 at 19:25











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419619%2fwhen-is-streamwriter-disposed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
4
down vote



accepted










The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.



The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.



You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.






share|improve this answer





















  • Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
    – bubbleking
    Nov 21 at 21:05










  • Yes removing the finalizer would be the "hope for the best" option.
    – Scott Chamberlain
    Nov 22 at 0:59










  • I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
    – bubbleking
    Nov 22 at 12:23










  • Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
    – bubbleking
    Nov 22 at 12:28










  • I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
    – Scott Chamberlain
    Nov 22 at 19:25















up vote
4
down vote



accepted










The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.



The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.



You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.






share|improve this answer





















  • Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
    – bubbleking
    Nov 21 at 21:05










  • Yes removing the finalizer would be the "hope for the best" option.
    – Scott Chamberlain
    Nov 22 at 0:59










  • I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
    – bubbleking
    Nov 22 at 12:23










  • Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
    – bubbleking
    Nov 22 at 12:28










  • I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
    – Scott Chamberlain
    Nov 22 at 19:25













up vote
4
down vote



accepted







up vote
4
down vote



accepted






The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.



The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.



You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.






share|improve this answer












The only things you are allowed to access in a finalizer are objects that are rooted (like static variables) or objects that derive from CriticalFinalizerObject.



The problem is the finalizer is not deterministic, it is allowed to run in any order it feels like. The problem you ran in to is because the text writer was finalized before your class.



You need to either just "hope for the best" and let the writer's finalizer to do the work or you need to refactor your code so your class is disposeable itself and that calls the stream writer's dispose method.







share|improve this answer












share|improve this answer



share|improve this answer










answered Nov 21 at 20:04









Scott Chamberlain

97.5k24177317




97.5k24177317












  • Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
    – bubbleking
    Nov 21 at 21:05










  • Yes removing the finalizer would be the "hope for the best" option.
    – Scott Chamberlain
    Nov 22 at 0:59










  • I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
    – bubbleking
    Nov 22 at 12:23










  • Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
    – bubbleking
    Nov 22 at 12:28










  • I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
    – Scott Chamberlain
    Nov 22 at 19:25


















  • Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
    – bubbleking
    Nov 21 at 21:05










  • Yes removing the finalizer would be the "hope for the best" option.
    – Scott Chamberlain
    Nov 22 at 0:59










  • I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
    – bubbleking
    Nov 22 at 12:23










  • Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
    – bubbleking
    Nov 22 at 12:28










  • I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
    – Scott Chamberlain
    Nov 22 at 19:25
















Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
– bubbleking
Nov 21 at 21:05




Would "hope for the best" be what my class would be doing if I were to simply remove the finalizer and leave the rest unchanged? I'm a bit surprised by your answer and the comments suggesting I implement IDisposable on my class. I'm familiar with that concept, and have done so before, but I thought there was some way to simply call an IDisposable's Dispose method without needing a using block to trigger it. I was hoping for a "has-a" instead of an "is-a" approach with this class, and implementing IDisposable is probably not an option here (the consuming code can't use a using block either).
– bubbleking
Nov 21 at 21:05












Yes removing the finalizer would be the "hope for the best" option.
– Scott Chamberlain
Nov 22 at 0:59




Yes removing the finalizer would be the "hope for the best" option.
– Scott Chamberlain
Nov 22 at 0:59












I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
– bubbleking
Nov 22 at 12:23




I decided to go with just implementing IDisposable, but not the pattern that includes the virtual method with the boolean disposing parameter and the call to GC.SuppressFinalizer. This project wasn't worth creating a whole base class hierarchy just for that. Instead, I merely called the StreamWriter's Dispose() method from my class' Dispose() method, and I found a place to use my class in a using block (which was a bit hacky, but it works). It's basically like the accepted answer on this: stackoverflow.com/questions/10038321/…
– bubbleking
Nov 22 at 12:23












Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
– bubbleking
Nov 22 at 12:28




Do you have any thoughts on that simple version (in my previous comment's link)? I'm not sure why the only recommendation one can ever find is to implement that entire IDisposable base class with public and virtual protected methods, and make the call to GC.SupressFinalize(). It seems like the simple version should do the job, but I guess there's something wrong with it, since you never see it in docs or recommendations. I guess I'm still just hoping for the best. ;)
– bubbleking
Nov 22 at 12:28












I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
– Scott Chamberlain
Nov 22 at 19:25




I think the advice to have a virtual method with a bool is a bad pattern, IMHO. Here is a good article that explains a better patern that you will never need to check for that bool again codeproject.com/Articles/29534/…
– Scott Chamberlain
Nov 22 at 19:25


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53419619%2fwhen-is-streamwriter-disposed%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Berounka

Sphinx de Gizeh

Different font size/position of beamer's navigation symbols template's content depending on regular/plain...