does aborting a thread while in 'using' block dispose used instance
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
|
show 4 more comments
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
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 theusingstatement 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 thinkThread.Abortis 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
|
show 4 more comments
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
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
c# multithreading
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 theusingstatement 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 thinkThread.Abortis 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
|
show 4 more comments
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 theusingstatement 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 thinkThread.Abortis 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
|
show 4 more comments
2 Answers
2
active
oldest
votes
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 aThreadAbortExceptionin 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.
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 callResetAbortand prevent the effect of theThreadAbortException.
– 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 thetry / finallyis nested in anothertry / finallywith 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
|
show 7 more comments
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
I don't think the question is about howusingworks, 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 callfinallyand since it's basically translated into atry finallyit 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
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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 aThreadAbortExceptionin 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.
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 callResetAbortand prevent the effect of theThreadAbortException.
– 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 thetry / finallyis nested in anothertry / finallywith 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
|
show 7 more comments
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 aThreadAbortExceptionin 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.
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 callResetAbortand prevent the effect of theThreadAbortException.
– 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 thetry / finallyis nested in anothertry / finallywith 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
|
show 7 more comments
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 aThreadAbortExceptionin 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.
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 aThreadAbortExceptionin 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.
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 callResetAbortand prevent the effect of theThreadAbortException.
– 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 thetry / finallyis nested in anothertry / finallywith 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
|
show 7 more comments
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 callResetAbortand prevent the effect of theThreadAbortException.
– 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 thetry / finallyis nested in anothertry / finallywith 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
|
show 7 more comments
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
I don't think the question is about howusingworks, 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 callfinallyand since it's basically translated into atry finallyit 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
add a comment |
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
I don't think the question is about howusingworks, 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 callfinallyand since it's basically translated into atry finallyit 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
add a comment |
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
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
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 howusingworks, 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 callfinallyand since it's basically translated into atry finallyit 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
add a comment |
I don't think the question is about howusingworks, 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 callfinallyand since it's basically translated into atry finallyit 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
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
usingstatement 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.Abortis 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