does aborting a thread while in 'using' block dispose used instance












4















I'm starting a thread like this:



nameOfThread = new Thread(() => 
{
//do stuff
});
nameOfThread.Start();


At some point inside this anonymous function I open a WinSCP session like this:



using (Session session = new Session())
{
//do stuff
}


If I abort the thread (from somewhere else) like this nameOfThread.Abort() while still doing stuff inside using, is the session disposed at the end?










share|improve this question


















  • 2





    Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

    – Panagiotis Kanavos
    Nov 27 '18 at 13:27











  • Yes, whether aborted or not the using statement still disposes properly.

    – Michael Puckett II
    Nov 27 '18 at 13:27











  • Why are you using a thread directly instead of eg Task.Run?

    – Panagiotis Kanavos
    Nov 27 '18 at 13:28













  • If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

    – Damien_The_Unbeliever
    Nov 27 '18 at 13:29











  • @PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

    – Angelo
    Nov 27 '18 at 13:30
















4















I'm starting a thread like this:



nameOfThread = new Thread(() => 
{
//do stuff
});
nameOfThread.Start();


At some point inside this anonymous function I open a WinSCP session like this:



using (Session session = new Session())
{
//do stuff
}


If I abort the thread (from somewhere else) like this nameOfThread.Abort() while still doing stuff inside using, is the session disposed at the end?










share|improve this question


















  • 2





    Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

    – Panagiotis Kanavos
    Nov 27 '18 at 13:27











  • Yes, whether aborted or not the using statement still disposes properly.

    – Michael Puckett II
    Nov 27 '18 at 13:27











  • Why are you using a thread directly instead of eg Task.Run?

    – Panagiotis Kanavos
    Nov 27 '18 at 13:28













  • If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

    – Damien_The_Unbeliever
    Nov 27 '18 at 13:29











  • @PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

    – Angelo
    Nov 27 '18 at 13:30














4












4








4


1






I'm starting a thread like this:



nameOfThread = new Thread(() => 
{
//do stuff
});
nameOfThread.Start();


At some point inside this anonymous function I open a WinSCP session like this:



using (Session session = new Session())
{
//do stuff
}


If I abort the thread (from somewhere else) like this nameOfThread.Abort() while still doing stuff inside using, is the session disposed at the end?










share|improve this question














I'm starting a thread like this:



nameOfThread = new Thread(() => 
{
//do stuff
});
nameOfThread.Start();


At some point inside this anonymous function I open a WinSCP session like this:



using (Session session = new Session())
{
//do stuff
}


If I abort the thread (from somewhere else) like this nameOfThread.Abort() while still doing stuff inside using, is the session disposed at the end?







c# multithreading






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 27 '18 at 13:25









AngeloAngelo

568




568








  • 2





    Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

    – Panagiotis Kanavos
    Nov 27 '18 at 13:27











  • Yes, whether aborted or not the using statement still disposes properly.

    – Michael Puckett II
    Nov 27 '18 at 13:27











  • Why are you using a thread directly instead of eg Task.Run?

    – Panagiotis Kanavos
    Nov 27 '18 at 13:28













  • If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

    – Damien_The_Unbeliever
    Nov 27 '18 at 13:29











  • @PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

    – Angelo
    Nov 27 '18 at 13:30














  • 2





    Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

    – Panagiotis Kanavos
    Nov 27 '18 at 13:27











  • Yes, whether aborted or not the using statement still disposes properly.

    – Michael Puckett II
    Nov 27 '18 at 13:27











  • Why are you using a thread directly instead of eg Task.Run?

    – Panagiotis Kanavos
    Nov 27 '18 at 13:28













  • If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

    – Damien_The_Unbeliever
    Nov 27 '18 at 13:29











  • @PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

    – Angelo
    Nov 27 '18 at 13:30








2




2





Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

– Panagiotis Kanavos
Nov 27 '18 at 13:27





Why abor the thread? Use a CancellationTokenSource and gracefully signal to the worker method that it needs to terminate

– Panagiotis Kanavos
Nov 27 '18 at 13:27













Yes, whether aborted or not the using statement still disposes properly.

– Michael Puckett II
Nov 27 '18 at 13:27





Yes, whether aborted or not the using statement still disposes properly.

– Michael Puckett II
Nov 27 '18 at 13:27













Why are you using a thread directly instead of eg Task.Run?

– Panagiotis Kanavos
Nov 27 '18 at 13:28







Why are you using a thread directly instead of eg Task.Run?

– Panagiotis Kanavos
Nov 27 '18 at 13:28















If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

– Damien_The_Unbeliever
Nov 27 '18 at 13:29





If you have a problem and think Thread.Abort is part of the solution, you've found the wrong solution. Heed the warnings in the documentation

– Damien_The_Unbeliever
Nov 27 '18 at 13:29













@PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

– Angelo
Nov 27 '18 at 13:30





@PanagiotisKanavos because I'm not really a savy when it comes to multithreading. but this doesn't answer the question

– Angelo
Nov 27 '18 at 13:30












2 Answers
2






active

oldest

votes


















3














Most likely it will, but you can't be sure.



According to the documentation:




When this method [Abort] is invoked on a thread, the system throws a ThreadAbortException in the thread to abort it.




And we know exceptions will still let using statements dispose, as they should. (Give and take a few exceptions)



On the other hand, if you can end the thread gracefully, for example with a CancellationTokenSource, it would be a lot nicer for your app. It will offer much more control over the actual termination of your thread and the handling of exceptions.






share|improve this answer


























  • Alright, thanks for the answer and alternative. I will study multi threading more.

    – Angelo
    Nov 27 '18 at 13:35











  • Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

    – Brian Rasmussen
    Nov 27 '18 at 13:39






  • 1





    You'll find the inconvenient truth in this post.

    – Hans Passant
    Nov 27 '18 at 13:46











  • @HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

    – Michael Puckett II
    Nov 27 '18 at 13:49













  • That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

    – Hans Passant
    Nov 27 '18 at 13:53





















1














I answered you can guarantee that the using statement will always call Dispose and I stand corrected, I was wrong.



There is a potential race condition with the using statement that doesn't guarantee disposing and I've put together a console app illustrating this (which isn't hard or trivial).



I was correct when showing how the IL generates using like so:



var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}


However; note the comments where I show the race condition that may occur if aborted before entering try.



Here is a console app written just to prove this point. The first works as expected but if you add the commented out code //thread.Abort() when we initialize R then you will see it init but never dispose :/



using System;
using System.Threading;

namespace Question_Answer_Console_App
{
class Program
{
static void Main(string args)
{
Console.WriteLine("Start Main");

Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));

thread.Start();
thread.Join();

Console.WriteLine("End Main");
Console.ReadKey();
}
}

public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}

public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}


Output with //thread.Abort() commented out:



Start Main
Thread Started
Init R
Using R
Disposed R
End Main


Output with thread.Abort() not commented out:



Start Main
Thread Started
Init R
End Main





share|improve this answer


























  • I don't think the question is about how using works, but how a thread abort has effect on it.

    – Patrick Hofman
    Nov 27 '18 at 13:39











  • @PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

    – Michael Puckett II
    Nov 27 '18 at 13:42











  • @PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

    – Michael Puckett II
    Nov 27 '18 at 13:45











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',
autoActivateHeartbeat: false,
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%2f53500763%2fdoes-aborting-a-thread-while-in-using-block-dispose-used-instance%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























2 Answers
2






active

oldest

votes








2 Answers
2






active

oldest

votes









active

oldest

votes






active

oldest

votes









3














Most likely it will, but you can't be sure.



According to the documentation:




When this method [Abort] is invoked on a thread, the system throws a ThreadAbortException in the thread to abort it.




And we know exceptions will still let using statements dispose, as they should. (Give and take a few exceptions)



On the other hand, if you can end the thread gracefully, for example with a CancellationTokenSource, it would be a lot nicer for your app. It will offer much more control over the actual termination of your thread and the handling of exceptions.






share|improve this answer


























  • Alright, thanks for the answer and alternative. I will study multi threading more.

    – Angelo
    Nov 27 '18 at 13:35











  • Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

    – Brian Rasmussen
    Nov 27 '18 at 13:39






  • 1





    You'll find the inconvenient truth in this post.

    – Hans Passant
    Nov 27 '18 at 13:46











  • @HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

    – Michael Puckett II
    Nov 27 '18 at 13:49













  • That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

    – Hans Passant
    Nov 27 '18 at 13:53


















3














Most likely it will, but you can't be sure.



According to the documentation:




When this method [Abort] is invoked on a thread, the system throws a ThreadAbortException in the thread to abort it.




And we know exceptions will still let using statements dispose, as they should. (Give and take a few exceptions)



On the other hand, if you can end the thread gracefully, for example with a CancellationTokenSource, it would be a lot nicer for your app. It will offer much more control over the actual termination of your thread and the handling of exceptions.






share|improve this answer


























  • Alright, thanks for the answer and alternative. I will study multi threading more.

    – Angelo
    Nov 27 '18 at 13:35











  • Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

    – Brian Rasmussen
    Nov 27 '18 at 13:39






  • 1





    You'll find the inconvenient truth in this post.

    – Hans Passant
    Nov 27 '18 at 13:46











  • @HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

    – Michael Puckett II
    Nov 27 '18 at 13:49













  • That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

    – Hans Passant
    Nov 27 '18 at 13:53
















3












3








3







Most likely it will, but you can't be sure.



According to the documentation:




When this method [Abort] is invoked on a thread, the system throws a ThreadAbortException in the thread to abort it.




And we know exceptions will still let using statements dispose, as they should. (Give and take a few exceptions)



On the other hand, if you can end the thread gracefully, for example with a CancellationTokenSource, it would be a lot nicer for your app. It will offer much more control over the actual termination of your thread and the handling of exceptions.






share|improve this answer















Most likely it will, but you can't be sure.



According to the documentation:




When this method [Abort] is invoked on a thread, the system throws a ThreadAbortException in the thread to abort it.




And we know exceptions will still let using statements dispose, as they should. (Give and take a few exceptions)



On the other hand, if you can end the thread gracefully, for example with a CancellationTokenSource, it would be a lot nicer for your app. It will offer much more control over the actual termination of your thread and the handling of exceptions.







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 27 '18 at 14:12

























answered Nov 27 '18 at 13:29









Patrick HofmanPatrick Hofman

127k18174232




127k18174232













  • Alright, thanks for the answer and alternative. I will study multi threading more.

    – Angelo
    Nov 27 '18 at 13:35











  • Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

    – Brian Rasmussen
    Nov 27 '18 at 13:39






  • 1





    You'll find the inconvenient truth in this post.

    – Hans Passant
    Nov 27 '18 at 13:46











  • @HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

    – Michael Puckett II
    Nov 27 '18 at 13:49













  • That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

    – Hans Passant
    Nov 27 '18 at 13:53





















  • Alright, thanks for the answer and alternative. I will study multi threading more.

    – Angelo
    Nov 27 '18 at 13:35











  • Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

    – Brian Rasmussen
    Nov 27 '18 at 13:39






  • 1





    You'll find the inconvenient truth in this post.

    – Hans Passant
    Nov 27 '18 at 13:46











  • @HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

    – Michael Puckett II
    Nov 27 '18 at 13:49













  • That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

    – Hans Passant
    Nov 27 '18 at 13:53



















Alright, thanks for the answer and alternative. I will study multi threading more.

– Angelo
Nov 27 '18 at 13:35





Alright, thanks for the answer and alternative. I will study multi threading more.

– Angelo
Nov 27 '18 at 13:35













Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

– Brian Rasmussen
Nov 27 '18 at 13:39





Keep in mind that the thread could call ResetAbort and prevent the effect of the ThreadAbortException.

– Brian Rasmussen
Nov 27 '18 at 13:39




1




1





You'll find the inconvenient truth in this post.

– Hans Passant
Nov 27 '18 at 13:46





You'll find the inconvenient truth in this post.

– Hans Passant
Nov 27 '18 at 13:46













@HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

– Michael Puckett II
Nov 27 '18 at 13:49







@HansPassant This should no longer be true. I remember reading this was solved in earlier versions of .NET, not sure which, where now the try / finally is nested in another try / finally with some other thread management to care for it. Not to confuse the OP but it's a bit of behind the scenes work to make sure this doesn't happen anymore. Looking at it, as is, without the race condition should be resolved as accurate and thread safe in current .NET releases. I'll have to look back into it to see when this was updated.

– Michael Puckett II
Nov 27 '18 at 13:49















That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

– Hans Passant
Nov 27 '18 at 13:53







That's an interesting tidbit that deserves better annotation, given that this does not yet happen on my machine in .NET 4.7.2 and C# v7.3.

– Hans Passant
Nov 27 '18 at 13:53















1














I answered you can guarantee that the using statement will always call Dispose and I stand corrected, I was wrong.



There is a potential race condition with the using statement that doesn't guarantee disposing and I've put together a console app illustrating this (which isn't hard or trivial).



I was correct when showing how the IL generates using like so:



var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}


However; note the comments where I show the race condition that may occur if aborted before entering try.



Here is a console app written just to prove this point. The first works as expected but if you add the commented out code //thread.Abort() when we initialize R then you will see it init but never dispose :/



using System;
using System.Threading;

namespace Question_Answer_Console_App
{
class Program
{
static void Main(string args)
{
Console.WriteLine("Start Main");

Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));

thread.Start();
thread.Join();

Console.WriteLine("End Main");
Console.ReadKey();
}
}

public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}

public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}


Output with //thread.Abort() commented out:



Start Main
Thread Started
Init R
Using R
Disposed R
End Main


Output with thread.Abort() not commented out:



Start Main
Thread Started
Init R
End Main





share|improve this answer


























  • I don't think the question is about how using works, but how a thread abort has effect on it.

    – Patrick Hofman
    Nov 27 '18 at 13:39











  • @PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

    – Michael Puckett II
    Nov 27 '18 at 13:42











  • @PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

    – Michael Puckett II
    Nov 27 '18 at 13:45
















1














I answered you can guarantee that the using statement will always call Dispose and I stand corrected, I was wrong.



There is a potential race condition with the using statement that doesn't guarantee disposing and I've put together a console app illustrating this (which isn't hard or trivial).



I was correct when showing how the IL generates using like so:



var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}


However; note the comments where I show the race condition that may occur if aborted before entering try.



Here is a console app written just to prove this point. The first works as expected but if you add the commented out code //thread.Abort() when we initialize R then you will see it init but never dispose :/



using System;
using System.Threading;

namespace Question_Answer_Console_App
{
class Program
{
static void Main(string args)
{
Console.WriteLine("Start Main");

Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));

thread.Start();
thread.Join();

Console.WriteLine("End Main");
Console.ReadKey();
}
}

public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}

public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}


Output with //thread.Abort() commented out:



Start Main
Thread Started
Init R
Using R
Disposed R
End Main


Output with thread.Abort() not commented out:



Start Main
Thread Started
Init R
End Main





share|improve this answer


























  • I don't think the question is about how using works, but how a thread abort has effect on it.

    – Patrick Hofman
    Nov 27 '18 at 13:39











  • @PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

    – Michael Puckett II
    Nov 27 '18 at 13:42











  • @PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

    – Michael Puckett II
    Nov 27 '18 at 13:45














1












1








1







I answered you can guarantee that the using statement will always call Dispose and I stand corrected, I was wrong.



There is a potential race condition with the using statement that doesn't guarantee disposing and I've put together a console app illustrating this (which isn't hard or trivial).



I was correct when showing how the IL generates using like so:



var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}


However; note the comments where I show the race condition that may occur if aborted before entering try.



Here is a console app written just to prove this point. The first works as expected but if you add the commented out code //thread.Abort() when we initialize R then you will see it init but never dispose :/



using System;
using System.Threading;

namespace Question_Answer_Console_App
{
class Program
{
static void Main(string args)
{
Console.WriteLine("Start Main");

Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));

thread.Start();
thread.Join();

Console.WriteLine("End Main");
Console.ReadKey();
}
}

public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}

public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}


Output with //thread.Abort() commented out:



Start Main
Thread Started
Init R
Using R
Disposed R
End Main


Output with thread.Abort() not commented out:



Start Main
Thread Started
Init R
End Main





share|improve this answer















I answered you can guarantee that the using statement will always call Dispose and I stand corrected, I was wrong.



There is a potential race condition with the using statement that doesn't guarantee disposing and I've put together a console app illustrating this (which isn't hard or trivial).



I was correct when showing how the IL generates using like so:



var session = new Session(); //If this causes an error or abort happens during initialization then we don't enter try
//If abort is called here then we never enter try
//In either case above we may have undisposed resources initialized at this point
try
{
//do stuff
}
finally
{
session.Dispose();
}


However; note the comments where I show the race condition that may occur if aborted before entering try.



Here is a console app written just to prove this point. The first works as expected but if you add the commented out code //thread.Abort() when we initialize R then you will see it init but never dispose :/



using System;
using System.Threading;

namespace Question_Answer_Console_App
{
class Program
{
static void Main(string args)
{
Console.WriteLine("Start Main");

Thread thread = null;
thread = new Thread(new ThreadStart(() =>
{
Console.WriteLine("Thread Started");
using (var r = new R(thread))
{
Console.WriteLine($"Using {nameof(R)}");
}
}));

thread.Start();
thread.Join();

Console.WriteLine("End Main");
Console.ReadKey();
}
}

public class R : IDisposable
{
public R(Thread thread)
{
Console.WriteLine($"Init {nameof(R)}");
//thread.Abort();
}

public void Dispose()
{
Console.WriteLine($"Disposed {nameof(R)}");
}
}
}


Output with //thread.Abort() commented out:



Start Main
Thread Started
Init R
Using R
Disposed R
End Main


Output with thread.Abort() not commented out:



Start Main
Thread Started
Init R
End Main






share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 28 '18 at 3:13

























answered Nov 27 '18 at 13:32









Michael Puckett IIMichael Puckett II

4,34741436




4,34741436













  • I don't think the question is about how using works, but how a thread abort has effect on it.

    – Patrick Hofman
    Nov 27 '18 at 13:39











  • @PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

    – Michael Puckett II
    Nov 27 '18 at 13:42











  • @PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

    – Michael Puckett II
    Nov 27 '18 at 13:45



















  • I don't think the question is about how using works, but how a thread abort has effect on it.

    – Patrick Hofman
    Nov 27 '18 at 13:39











  • @PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

    – Michael Puckett II
    Nov 27 '18 at 13:42











  • @PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

    – Michael Puckett II
    Nov 27 '18 at 13:45

















I don't think the question is about how using works, but how a thread abort has effect on it.

– Patrick Hofman
Nov 27 '18 at 13:39





I don't think the question is about how using works, but how a thread abort has effect on it.

– Patrick Hofman
Nov 27 '18 at 13:39













@PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

– Michael Puckett II
Nov 27 '18 at 13:42





@PatrickHofman You're correct. Maybe I should have explained better but I did mention that a thread, even when aborted, will always call finally and since it's basically translated into a try finally it will dispose when aborted.

– Michael Puckett II
Nov 27 '18 at 13:42













@PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

– Michael Puckett II
Nov 27 '18 at 13:45





@PatrickHofman I updated the answer at the bottom to hopefully make it more clear.

– Michael Puckett II
Nov 27 '18 at 13:45


















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.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53500763%2fdoes-aborting-a-thread-while-in-using-block-dispose-used-instance%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

A CLEAN and SIMPLE way to add appendices to Table of Contents and bookmarks

Calculate evaluation metrics using cross_val_predict sklearn

Insert data from modal to MySQL (multiple modal on website)