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 theusing
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 thinkThread.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
|
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 theusing
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 thinkThread.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
|
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 theusing
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 thinkThread.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
|
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 aThreadAbortException
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.
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 callResetAbort
and 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 / finally
is nested in anothertry / 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
|
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 howusing
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 callfinally
and since it's basically translated into atry 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
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 aThreadAbortException
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.
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 callResetAbort
and 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 / finally
is nested in anothertry / 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
|
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 aThreadAbortException
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.
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 callResetAbort
and 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 / finally
is nested in anothertry / 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
|
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 aThreadAbortException
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.
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 aThreadAbortException
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.
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 callResetAbort
and 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 / finally
is nested in anothertry / 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
|
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 callResetAbort
and 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 / finally
is nested in anothertry / 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
|
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 howusing
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 callfinally
and since it's basically translated into atry 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
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 howusing
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 callfinally
and since it's basically translated into atry 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
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 howusing
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 callfinally
and since it's basically translated into atry 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
add a comment |
I don't think the question is about howusing
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 callfinally
and since it's basically translated into atry 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
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
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