How does ASP.NET HttpServerUtility.Transfer break the control flow? - c#

By "how does" I mean "by what mechanism" not "to what effect". Control doesn't return to the calling method after you call Server.Transfer("...");. At the language runtime level, how does this happen? Does it throw an exception or trigger something that aborts the thread? I'm just curious. What are other examples of this pattern (calling a method to terminate execution)?

It eventually calls End which throws a ThreadAbortException that terminates the current thread of execution. See the documentation here
http://msdn.microsoft.com/en-us/library/y4k58xk7.aspx

Related

Reactive Extensions swallows exceptions from OnNext() called on a thread pool thread?

I use Rx 2 in .Net 4.5. When the following code runs, it just exits silently without executing the OnCompleted delegate or showing any errors. If I use Scheduler.CurrentThread in ToObservable, it will at least throw the error and terminate the program, at which point not executing OnCompleted makes sense. But when this is executed in a thread other than the main one, this behavior seems unreasonable and unacceptable. Do I miss anything?
static void Main()
{
Enumerable.Range(0, 1)
.ToObservable(Scheduler.Default)
.Subscribe(o => { throw new Exception("blah"); }, () => Console.WriteLine("completed"));
Thread.Sleep(2000);
}
Edited:
Yes, when running as a console app, it will always throw the error regardless of what thread the observation is executed on.
However, when I run this code as a test in NUnit as follows, it exits silently after 2 seconds (thread sleep time) without any error or message (expecting "completed"). So is it actually NUnit causing the issue?
[TestFixture]
class Program
{
[Test]
public void Test()
{
Enumerable.Range(0, 1)
.ToObservable(Scheduler.Default)
.Subscribe(
o => { throw new Exception("blah"); },
() => Console.WriteLine("completed"));
Thread.Sleep(2000);
}
}
Rx does not catch exceptions thrown by observers. This is a very important design principle that has been discussed in length before, though for some reason it's only included as a footnote of §6.4 in the Rx Design Guidelines.
Note: do not protect calls to Subscribe, Dispose, OnNext, OnError and OnCompleted methods. These calls are on the edge of the monad. Calling the OnError method from these places will lead to unexpected behavior.
Essentially, this guideline ensures that, from the perspective of an observer, OnError will only be called by exceptions originating from the observable itself, including any calls to user code that participate directly in the computation (rather than merely observing the results). If this were not the case, then an observer may not be able to distinguish whether an exception passed to OnError is a bug in their OnNext handler or perhaps a bug in the observable.
But more importantly, it also ensures that any exception thrown by an OnNext handler goes unhandled. This makes it easier to debug your program and protects user data.
That being said, the reason why you may be observing different behavior when OnNext is executed on a pooled thread is simply a consequence of your debugging experience. Try enabling first-chance exceptions.
Furthermore, I'd also avoid the race condition by changing Thread.Sleep to Console.ReadKey().
Exceptions thrown in the Subscribe block have Undefined Behavior. If you are doing something that can throw, you need to wrap that in a Select or SelectMany (or just wrap the code in a try-catch).

can we use "goto" keyword to end a thread? [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
In many programming languages, many questions have been raised to stop execution of a thread.In c/c++ goto is still used, where as in Java , goto is not used,but still it's reserved; stop(), stop(Throwable) and suspend(), destroy() and resume(), which were intended to provide the basic functionality for starting and stopping a thread has been depreciated.
Can we use goto to simply to move out of a thread?
Somethig like this :
//Thread block
{...
if(some condition)
goto out;
.....
...
}//thread block over
out:
// I am out!!
}
I know using goto is a very very bad practice, but can still it be used like this?
UPDATE:
Or:
//Thread block
{...
if(some condition)
goto out;
.....
...
out:
// I am out!!
}//thread block over
From the comments,is this the solution?
UPDATE2:
Well,I am getting mix kind of answers.Some yes,some no.I don't use c/c++ much ,otherwise could have implemented and see myself.
This doesn't work.
You can't goto to another method.
A thread is not bound to a method and one method can be executed by multiple threads.
If the goto location would be in the same method, the execution would simply continue at the new location in the thread that executed the goto statement.
What you can do, is go to the end of the thread method - if the current code is in that method. This won't end the thread, but the goto will move the program flow just before the end of the thread method which will lead to the thread method being finished executing and thus ending the thread.
This is the same effect as simply returning from the thread method.
Absolutely, you can: you can use goto to transfer control unconditionally to the end of your method from almost anywhere, with very few restrictions. If this is the method that implements your thread, it will exit, ending the thread.
Whether you should is a different question: with very few exceptions, goto makes your program less readable; without exceptions, you can achieve the same result without a goto, and improve readability at the same time. For example, you could use return to end the method implementing the logic of your thread.
You can't "move out" of a thread using goto. A thread's execution is not limited to a given scope and just moving to another location in your code will not terminate it.
You can not goto to a label out of the your thread function
You can set the out: at the end of the thread functio. And in this way if you want to stop your thread you can goto the out: (from any place in your thread function) and the thread function will be stopped
If you want to execute some part of your code at the end of your thread you can use pthread_cond_signal(&cond);
the following link contains an example of how to use it: multithread launching order
No you can't.
But perhaps you don't need to... You can try to use ThreadAbortException (by calling Thread.Abort()) and catch it (yes, within the thread), executing the 'out' functionality, and do a Thread.ResetAbort. Just be careful and be sure to read up on the risks involved on MSDN when calling abort from another thread (which you don't seem to be doing).
See also: http://msdn.microsoft.com/en-us/library/ty8d3wta.aspx
First of all, putting cleanup code at end of function, and jumping to it with goto is quite valid pattern in C. Use it when ever it makes the code cleaner and easier to understand. Of course it can be abused, and it doesn't work that well when you have multiple levels of functions, so it might encourage making too long functions just to be able to goto to cleanup code. But as long as it's used carefully, goto is quite valid in C. Also, since the question is a bit vague, better say this explicitly: you can not goto between functions. And in languages supporting exceptions, you should use those instead of goto (of course you have to use them right too, not abuse them).
But often, especially with threads, it is better to register cleanup handlers for the thread, so you can then just return or call the thread frameworks "exit this thread" function, instead of using goto to cleanup code.
Finally, with the code above, with no code after out: label, you could just return instead of using goto... This assumes you are using a threading library, which takes a function to run in other thread, and will end the thread when that function returns.

Is it necessary to call EndInvoke in the callback from an EventHandler.BeginInvoke (C# .Net 3.5)

I'm setting up a WCF client and server scenario that needs to be reliable and scalable and as part of that I'm trying to make it multithreaded. Admittedly I don't have extensive multithreading experience.
On the client, the callback from the server (in this case "OnMessage") fires a client-side event that should be passed off in the background. I have the client's CallbackBehavior ConcurrencyMode set to Single (at least, for now). So in order to do a reply to the callback, rather than calling the handler as normal (either handler(sender, eventargs, or handler.Invoke...) I'm calling handler.BeginInvoke.
Everything works fine, but in the callback I'm wondering if I need to explicitly call EndInvoke or if I can basically do nothing (here's my lack of multithreading experience showing).
public void OnMessage(Message message)
{
EventHandler<MessageEventArgs> handler = OnServerMessage;
if (handler != null)
handler.BeginInvoke(this, new MessageEventArgs(message), CompleteHandler, handler);
}
public void CompleteHandler(IAsyncResult result)
{
((EventHandler<MessageEventArgs>)result.AsyncState).EndInvoke(result);
}
Can I replace CompleteHandler with a direct reference to handler.EndInvoke, or an empty method, or perhaps is there something more I should be doing?
Also, at the moment, the event subscriber blocks waiting on user input from the console. When the application is complete, it would either block waiting on the database, or be asynchronous bottom-to-top (so this may not be necessary, but I'd still like to know).
Yes you have to. Only way to find out if the invoked method threw an exception. And to cleanup the remoting state of the call so it can be garbage collected instead of letting it linger for another 10 minutes.
You need to wrap your CompleteHandler code in a try/catch block and then properly handle any exception thrown by the EndInvoke. Right now the service works under 'lab' conditions, but when things go wrong you won't even know what goes wrong, because you don't handle/log errors properly.
As for the issue of getting the state from the global state, or from the IAsyncResult, or from a callback closure: IASyncResult.AsyncState is the most generic solution and will continue to work correctly after somebody else refactors the calling code beyond any recognition.
In general, BeginInvoke starts an asynchronous operation, whereas EndInvoke waits for it to finish. So it depends on your intention: if you want to guarantee that your asynchronous code is finished, you need EndInvoke, otherwise no.
(Beware however that if your BeginInvoke calls into the same thread where you actually are (it's a valid usage, just the code will be run on the next Dispatcher loop), you must not use EndInvoke, as this would create a deadlock. But this seems to be not your case.)

Is C#'s using statement abort-safe?

I've just finished reading "C# 4.0 in a Nutshell" (O'Reilly) and I think it's a great book for a programmer willing to switch to C#, but it left me wondering. My problem is the definition of using statement. According to the book (p. 138),
using (StreamReader reader = File.OpenText("file.txt")) {
...
}
is precisely equivalent to:
StreamReader reader = File.OpenText("file.txt");
try {
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
Suppose, however, that this is true and that this code is executed in a separate thread. This thread is now aborted with thread.Abort(), so a ThreadAbortException is thrown and suppose the thread is exactly after initializing the reader and before entering the try..finally clause. This would mean that the reader is not disposed!
A possible solution would be to code this way:
StreamReader reader = null;
try {
reader = File.OpenText("file.txt");
...
} finally {
if (reader != null)
((IDisposable)reader).Dispose();
}
This would be abort-safe.
Now for my questions:
Are authors of the book right and the using statement is not abort-safe or are they wrong and it behaves like in my second solution?
If using is equivalent to the first variant (not abort-safe), why does it check for null in finally?
According to the book (p. 856), ThreadAbortException can be thrown anywhere in managed code. But maybe there are exceptions and the first variant is abort-safe after all?
EDIT: I know that using thread.Abort() is not considered good practice. My interest is purely theoretical: how does the using statement behave exactly?
The book's companion web site has more info on aborting threads here.
In short, the first translation is correct (you can tell by looking at the IL).
The answer to your second question is that there may be scenarios where the variable can be legitimately null. For instance, GetFoo() may return null here, in which you wouldn't want a NullReferenceException thrown in the implicit finally block:
using (var x = GetFoo())
{
...
}
To answer your third question, the only way to make Abort safe (if you're calling Framework code) is to tear down the AppDomain afterward. This is actually a practical solution in many cases (it's exactly what LINQPad does whenever you cancel a running query).
There's really no difference between your two scenarios -- in the second, the ThreadAbort could still happen after the call to OpenText, but before the result is assigned to the reader.
Basically, all bets are off when you get a ThreadAbortException. That's why you should never purposely abort threads rather than using some other method of gracefully bringing the thread to a close.
In response to your edit -- I would point out again that your two scenarios are actually identical. The 'reader' variable will be null unless the File.OpenText call successfully completes and returns a value, so there's no difference between writing the code out the first way vs. the second.
Thread.Abort is very very bad juju; if people are calling that you're already in a lot of trouble (unrecoverable locks, etc). Thread.Abort should really be limited to the scanerio of inhuming a sickly process.
Exceptions are generally unrolled cleanly, but in extreme cases there is no guarantee that every bit of code can execute. A more pressing example is "what happens if the power fails?".
Re the null check; what if File.OpenText returned null? OK, it won't but the compiler doesn't know that.
A bit offtopic but the behaviour of the lock statement during thread abortion is interesting too. While lock is equivalent to:
object obj = x;
System.Threading.Monitor.Enter(obj);
try {
…
}
finally {
System.Threading.Monitor.Exit(obj);
}
It is guaranteed(by the x86 JITter) that the thread abort doesn't occur between Monitor.Enter and the try statement.
http://blogs.msdn.com/b/ericlippert/archive/2007/08/17/subtleties-of-c-il-codegen.aspx
The generated IL code seems to be different in .net 4:
http://blogs.msdn.com/b/ericlippert/archive/2009/03/06/locks-and-exceptions-do-not-mix.aspx
The language spec clearly states that the first one is correct.
http://msdn.microsoft.com/en-us/vcsharp/aa336809.aspx MS Spec(Word document)
http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-334.pdf ECMA Spec
In case of a thread aborting both code variants can fail. The second one if the abort occurs after the expression has been evaluated but before the assignment to the local variable occurred.
But you shouldn't use thread abortion anyways since it can easily corrupt the state of the appdomain. So only abort threads if you force unload an appdomain.
You are focusing on the wrong problem. The ThreadAbortException is just as likely to abort the OpenText() method. You might hope that it is resilient to that but it isn't. The framework methods do not have try/catch clauses that try to deal with a thread abort.
Do note that the file doesn't remain opened forever. The FileStream finalizer will, eventually, close the file handle. This of course can still cause exceptions in your program when you keep running and try to open the file again before the finalizer runs. Albeit that this is something you always have to be defensive about when you run on a multi-tasking operating system.
Are authors of the book right and the using statement is not abort-safe or are they wrong and it behaves like in my second solution?
According to the book (p. 856), ThreadAbortException can be thrown anywhere in managed code. But maybe there are exceptions and the first variant is abort-safe after all?
The authors are right. The using block is not abort-safe. Your second solution is also not abort-safe, the thread could be aborted in the middle of the resource acquisition.
Although it's not abort-safe, any disposable that has unmanged resources should also implement a finalizer, which will eventually run and clean up the resource. The finalizer should be robust enough to also take care of not completely initialized objects, in case the thread aborts in the middle of the resource acquisition.
A Thread.Abort will only wait for code running inside Constrained Execution Regions (CERs), finally blocks, catch blocks, static constructors, and unmanaged code. So this is an abort-safe solution (only regarding the acquisition and disposal of the resource):
StreamReader reader = null;
try {
try { }
finally { reader = File.OpenText("file.txt"); }
// ...
}
finally {
if (reader != null) reader.Dispose();
}
But be careful, abort-safe code should run fast and not block. It could hang a whole app domain unload operation.
If using is equivalent to the first variant (not abort-safe), why does it check for null in finally?
Checking for null makes the using pattern safe in the presence of null references.
The former is indeed exactly equivalent to the latter.
As already pointed out, ThreadAbort is indeed a bad thing, but it's not quite the same as killing the task with Task Manager or switching off your PC.
ThreadAbort is an managed exception, which the runtime will raise when it is possible, and only then.
That said, once you're into ThreadAbort, why bother trying to cleanup? You're in death throes anyway.
the finally-statement is always executed, MSDN says "finally is used to guarantee a statement block of code executes regardless of how the preceding try block is exited."
So you don't have to worry about not cleaning resources etc (only if windows, the Framework-Runtime or anything else bad you can't control happens, but then there are bigger problems than cleaning up Resources ;-))

ThreadAbortException vs graceful event handle exit in C#

When aborting the execution of a thread I'm always doubting between a graceful exit with an event handler like this:
int result = WaitHandle.WaitAny(handles);
if (result = WAIT_FINALIZE)
FinalizeAndExit();
and using the event to signal the thread it must terminate
or just handling the ThreadAbortException to finalize the thread...
try
{
// Main execution
}
catch(ThreadAbortException e)
{
// FinalizeAndExit();
}
finally
{
}
I'm usually inclined to use the ThreadAbortException approach since it can be handled but it is re-raised at the end of the catch block, and it also avoids the thread from being kept alive by "treacherous" methods, but I've seen both approaches.
What's your opinion? Is there any situation where it's best to use one over another, or is it best to use always approach x?
Generally, the first method it preferrable.
It's hard (if not impossible) to write code that will always handle a ThreadAbortException gracefully. The exception can occur in the middle of whatever the thread happens to be doing, so some situations can be hard to handle.
For example, the exception can occur after you have created a FileStream object, but before the reference is assigned to a variable. That means that you have an object that should be disposed, but the only reference to it is lost on the stack somewhere...
If I can I try to avoid using Thread.Abort.
The problem with Thread.Abort is that it could happen in (almost) any line of the executing code and might cause some "interesting" behavior (read: bugs).
Intead I prefer to have a point of exit on my code that checks for an event or variable to see if it the thread should stop running and gracefully exit.
Surely if the termination event is expected then it's not an exception (by the strict definition of the term) so therefore you should be using the first method. A graceful exit also shows that you are in control.
While exceptions are useful and in some cases necessary, they can and do get overused.

Categories

Resources