c# Exception thrown in a thread is caught in an other thread - c#

I read in this post (http://bytes.com/topic/c-sharp/answers/238006-cannot-catch-exception-thread#post970280) that: 'Thrown exceptions are stack-bound objects. Since every thread has its
own stack, an exception thrown in thread A cannot suddenly appear in
thread B'
But I have a project in which exactly this seems to happen. i am kind of desperate to find the source of my problem. what i am doing is calling 10 threads, of which each one runs several tools simultaneously. each tool is run in yet another thread by starting an executable in a process. this means if i have e.g. 2 tools i will have 10x2 threads in total. the problem is the following: if an exception is thrown, e.g. when one of the tool threads fails and i want to catch it inside the same thread, it happens that any of the threads catches the exception. I verify that by letting the run method output by letting the runTool function include the threadId and toolId in the exception that it throws and comparing the output from the throw and the catch
here the simplified code:
class Worker
{
private ManualResetEvent[] threadResetEvents;
private ManualResetEvent[][] toolResetEvents;
private Tool[] tools;
public int stopped = false;
public void run(int threadNo)
{
threadResetEvents = new ManualResetEvent[threadNo];
toolResetEvents = new ManualResetEvent[threadNo][];
for (int i = 0; i < threadNo; i++)
{
threadResetEvents[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(new WaitCallback(fillDb), (object)i);
}
sendToObservers("Filling database...");
WaitHandle.WaitAll(threadResetEvents);
}
private void fillDb(object obj)
{
int threadId = (int)obj;
while (!stopped)
{
toolResetEvents[threadId] = new ManualResetEvent[tools.Length];
for (int i = 0; i < tools.Length; i++)
{
toolResetEvents[threadId][i] = new ManualResetEvent(false);
ToolInfoObject info = new ToolInfoObject(threadId, i);
ThreadPool.QueueUserWorkItem(new WaitCallback(runTool), info);
}
WaitHandle.WaitAll(toolResetEvents[threadId]);
}
}
private void runTool(object obj)
{
ToolInfoObject info = (ToolInfoObject) i;
int threadId = info.threadId;
int toolId = info.toolId;
try
{
tools[toolId].runTool(threadId, toolId);
}
catch (Exception e)
{
Console.WriteLine("Exception caught in Thread " + threadId + ", Tool " + toolId + ": " + e.GetBaseException());
}
}
}
class ToolInfoObject
{
public int threadId;
public int toolId;
public ToolInfoObject(int thread, int tool)
{
this.threadId = thread;
this.toolId = tool;
}
}
I'd be grateful for any help
EDIT:
in more detail, the problem shows up when an IOException is thrown. i let every tool create a directory and files in it based on the thread number. if a file is not accessible it will lead to a message like this:
Exception caught in Thread 1, Tool 0: System.IO.FileNotFoundException: Die Datei "C:\tmpdir\3\log.txt" konnte nicht gefunden werden.
which means the exception actuall happened in thread 3, but was caught in thread 1

Check if your Tool is threadsafe. If it is not this can lead to your problem.

Related

stopped in the debugger with a C# thread hung on a lock statement, how do I figure out which thread currently owns the lock? [duplicate]

one of the threads in my application blocked at the following lock statement and resulted in a deadlock
void ExecuteCommand()
{
lock(this._lockinstance)
{
// do some operation
}
}
Is it possible to easily identify which thread is currently holding the lock?.. My application has more than 50 threads, which makes it difficult to go through each callstack using visual studio to locate the thread that holds the lock
Some sample code to try out:
class Test {
private object locker = new object();
public void Run() {
lock (locker) { // <== breakpoint here
Console.WriteLine(System.Threading.Thread.CurrentThread.ManagedThreadId);
}
}
}
Set a breakpoint on the indicated line. When it breaks, use Debug + Windows + Memory + Memory 1. Right click the window and choose "4-byte Integer". In the Address box, type &locker. The 2nd word is the thread ID of the thread that owns the lock. Step past the lock statement to see it change.
Beware that the number is the managed thread ID, not the operating system thread ID that you see in the Debug + Windows + Threads window. That kinda sucks, you probably should add some logging to your program that dumps the value of ManagedThreadId so you have a way to match the value to a thread. Update: fixed in later VS versions, the Debug > Windows > Threads debugger window now shows the ManagedThreadId.
Recently I was trying to determine what function was holding a lock and found the following very useful and had not seen in demonstrated anywhere before. I've placed it as an answer here in case others find it useful too.
Many of the other solutions posted earlier require writing a new class and then converting of all lock(blah) to BetterLock(blah) which is a lot of work for debugging and which you may not want in the production/shipped version of your code. Others required having the debugger attached which changes the code's timing and could obscure the issue.
Instead, try the following...
Original code:
object obj = new object();
lock(obj)
{
// Do stuff
}
Modified code for debugging:
object _obj = new object();
object obj
{
get
{
System.Diagnostics.StackFrame frame = new System.Diagnostics.StackFrame(1);
System.Diagnostics.Trace.WriteLine(String.Format("Lock acquired by: {0} on thread {1}", frame.GetMethod().Name, System.Threading.Thread.CurrentThread.ManagedThreadId));
return _obj;
}
}
// Note that the code within lock(obj) and the lock itself remain unchanged.
lock(obj)
{
// Do stuff
}
By exposing obj as a property, at least temporarily, with very minimal code changes you can determine what function acquired the lock last and on what thread - just look at the Trace output for the last entry. Of course you can output any other information you might find useful in the getter as well.
No, this will not let you determine when a lock was released, but if it was getting released in a timely fashion, then you didn't actually have a lock contention issue in the first place.
You can implement a Monitor wrapper that saves stack traces & thread names on enter.
Old way:
private object myLock = new object();
...
lock(myLock)
{
DoSomething();
}
...
With code below:
private SmartLock myLock = new SmartLock();
...
myLock.Lock( () =>
{
DoSomething();
}
);
...
Source:
public class SmartLock
{
private object LockObject = new object();
private string HoldingTrace = "";
private static int WARN_TIMEOUT_MS = 5000; //5 secs
public void Lock(Action action)
{
try
{
Enter();
action.Invoke();
}
catch (Exception ex)
{
Globals.Error("SmartLock Lock action", ex);
}
finally
{
Exit();
}
}
private void Enter()
{
try
{
bool locked = false;
int timeoutMS = 0;
while (!locked)
{
//keep trying to get the lock, and warn if not accessible after timeout
locked = Monitor.TryEnter(LockObject, WARN_TIMEOUT_MS);
if (!locked)
{
timeoutMS += WARN_TIMEOUT_MS;
Globals.Warn("Lock held: " + (timeoutMS / 1000) + " secs by " + HoldingTrace + " requested by " + GetStackTrace());
}
}
//save a stack trace for the code that is holding the lock
HoldingTrace = GetStackTrace();
}
catch (Exception ex)
{
Globals.Error("SmartLock Enter", ex);
}
}
private string GetStackTrace()
{
StackTrace trace = new StackTrace();
string threadID = Thread.CurrentThread.Name ?? "";
return "[" + threadID + "]" + trace.ToString().Replace('\n', '|').Replace("\r", "");
}
private void Exit()
{
try
{
Monitor.Exit(LockObject);
HoldingTrace = "";
}
catch (Exception ex)
{
Globals.Error("SmartLock Exit", ex);
}
}
}
Yes, there is a 'Threads' view that you can use in VS. Break anywhere in your application (or click the 'Break All' button) then you can select each thread and view who has the lock (if anyone).
To add it, go to Debug > Windows > Threads (Ctrl+D,T)
Old posts are old.
But i thought i might give a solution i find to be fairly useful for trying to track down dead locks and other locking problems.
I use a disposable class for my lock - I like Monitor but any locking mechanism could be used.
public class MonitorLock : IDisposable
{
public static MonitorLock CreateLock(object value)
{
return new MonitorLock(value);
}
private readonly object _l;
protected MonitorLock(object l)
{
_l = l;
Console.WriteLine("Lock {0} attempt by {1}", _l, Thread.CurrentThread.ManagedThreadId);
Monitor.Enter(_l);
Console.WriteLine("Lock {0} held by {1}" , _l, Thread.CurrentThread.ManagedThreadId);
}
public void Dispose()
{
Monitor.Exit(_l);
Console.WriteLine("Lock {0} released by {1}", _l, Thread.CurrentThread.ManagedThreadId);
}
}
I use a lock object with a name so I can be clear as to which lock I'm trying to aquire.
public class LockObject
{
public string Name { get; set; }
public LockObject(string name)
{
Name = name;
}
public override string ToString()
{
return Name;
}
}
Finally create a lock object, and then in a using block hold the object.
//create an object to lock on
private readonly object _requestLock = new LockObject("_requestLock");
using (MonitorLock.CreateLock(_requestLock))
{
//do some work
}
Output should be something along the lines of
Lock _requestLock attempt by 92
Lock _requestLock held by 92
Lock _requestLock attempt by 19
Lock _requestLock released by 92
Lock _requestLock held by 19
Lock _requestLock released by 19
Hope that someone finds this useful :)
The Managed Stack Explorer from http://mse.codeplex.com/ or http://www.microsoft.com/downloadS/details.aspx?FamilyID=80cf81f7-d710-47e3-8b95-5a6555a230c2&displaylang=en is excellent in such cases.
It hooks into running managed code (appropriate permissions needed) including live code, and grabs a list of running threads. You can double-click on any of them or (more useful in cases like this) select the lot and hit enter for a quick relatively non-invasive (obviously it's going to consume resources, but it goes in and out as quickly as it can) dump of the current stacks of different threads. Great for finding a deadlock, infinite loop, near-infinite loop (for those times when your application accidentally depends upon astronomers being pessimistic about how long the earth will last to have a hope of completing) and other such cases.
I'm not sure in which version this feature was added, but the Visual Studio 2022 debugger now shows in its Call Stack window the ID of the thread that owns the lock on which another thread is waiting to acquire, e.g.,
I found this over here.

Thread.Suspend() is obsolete

I have a problem with thread, I want to create n thread and write a log (with method write, already implemented)
This is an unit test, when I run it, it works nice, but an exception appears :
System.AppDomainUnloadedException: Attempted to access an unloaded AppDomain. This can happen if the test(s) started a thread but did not stop it. Make sure that all the threads started by the test(s) are stopped before completion.
So, I tried to use ThreadC.Suspend() and error disappears, but mehod Suspend is obsolete..
How can I fix it?
public void TestMethod1()
{
try
{
LogTest logTest = new LogTest(new FileLog());
logTest.PerformanceTest();
logTest = new LogTest(new CLogApi());
logTest.PerformanceTest();
logTest = new LogTest(new EmptyLog());
logTest.PerformanceTest();
}
catch (Exception)
{
Assert.IsTrue(false);
}
}
public class LogTest
{
private readonly Log log;
private int numberOfIterations = 5;
public LogTest(Log log)
{
this.log = log;
}
public void PerformanceTest()
{
for (int i = 0; i < this.numberOfIterations; i++)
{
try
{
Thread threadC = Thread.CurrentThread;
threadC = new Thread(this.ThreadProc);
threadC.Name = i.ToString();
threadC.Start();
// threadC.IsBackground = true;
}
catch (Exception)
{
Assert.IsTrue(false);
}
}
}
private void ThreadProc()
{
try
{
this.log.Write(" Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write(" Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write(" Thread : " + Thread.CurrentThread.Name.ToString());
this.log.Write(" Thread : " + Thread.CurrentThread.Name.ToString());
}
catch (Exception)
{
Assert.IsTrue(false);
}
}
}
1: You should use "Assert.Fail()" instead Assert.IsTrue(false);
2: Read the Microsoft documentation if you use an obsolete method. They write what you can use instead."Thread.Suspend has been deprecated. Please use other classes in System.Threading, such as Monitor, Mutex, Event, and Semaphore, to synchronize Threads or protect resources."
3: If i understand you correctly you want to kill all running threads or wait for them. You can use "Thread.Join()" https://msdn.microsoft.com/de-de/library/95hbf2ta(v=vs.110).aspx
You can store all threads in an Array or list an join all threads at the end.
4: Instead using threads you can use the async pattern and wait for all Tasks with Task.WaitAll(tasks) https://msdn.microsoft.com/en-us/library/dd270695(v=vs.110).aspx

throw an Exception in thread C#

I have thread Like this, after i see example link text
ThreadStart _threadStart = new ThreadStart(delegate()
{
try
{
threadFunction(httpContext);
}
catch (Exception ex)
{
throw ex;
}
});
Thread _thread = new Thread(_threadStart);
_thread.Start();
when an Exception happen it dosen't re-thrown in the thread that started it.
So what i'm doing wrong or how to do it?
Note: thanks to all comments in advanced
The exception will be thrown, but that will only end the thread. The exception isn't re-thrown in the thread that started it.
I think the heart of the matter is to understand that exceptions that occur within a thread will not be passed to the calling thread for handling.
For example, say you have a rebel method:
private static void RebelWithoutACause()
{
throw new NullReferenceException("Can't touch this!");
}
Let's say you create a new thread that calls this method in your program, and being a safe programmer, you decide to envelope the work in a try/catch block:
private static void Main(string[] args)
{
try
{
var thread = new Thread(RebelWithoutACause);
thread.Start();
thread.Join();
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
However, if you run this in the debugger, you will find out that you'll never get to the catch block, and instead the thread will be killed, and the debugger will complain that you have an unhandled exception.
You need to take your pick of how to handle the exceptions, but the handling needs to happen inside each thread entry method. Typical handling includes logging the details, notifying users via the UI, and shutting down your application as gracefully as you can.
Are you sure that the exception is thrown? If a thread fails with an exception, the whole application will crash, which you can notice using the AppDomain.CurrentDomain.UnhandledException event (note that by the time the event has fired, you cannot prevent your application from being ended, but can clean-up resources and save critical data - see the event documentation for more information).
But, to quote the accepted answer from the thread you referred to:
Any thread that raises a top-level exception indicates a big problem.
You should try logging the exception, and/or signaling the other thread(s) that this thread has failed.
The exception is being thrown, except I guess you do not see it, since it is thrown on another thread. Therefore, the UI thread (or whatever thread invoked the other thread), cannot catch the exception, since it doesn't see it.
If you log the exception to a file for instance, I'm sure you'll see it. :)
I think perhaps you should look at using the BackgroundWorker class. You can subscribe to the RunWorkerCompleted event, and it has an Error property that will contain your exception.
maybe do something like this:
const int numThreads = 8;
Thread[] threads = new Thread[numThreads];
Exception[] threadsExceptions = new Exception[numThreads];
for (int i = 0; i < numThreads; i++) {
threadsExceptions[i] = null;
int closureVariableValue = i;
ThreadStart command = () =>
{
try
{
throw new ArgumentException("thread_" + closureVariableValue + "'s exception");
}catch(Exception any)
{
threadsExceptions[closureVariableValue] = any;
}
};
threads[i] = new Thread(command);
threads[i].Start();
}
for(int i = 0; i < numThreads; i++)
{
threads[i].Join();
if (threadsExceptions[i] != null)
{
throw threadsExceptions[i];
}
}

Process is terminated due to StackOverflowException

This is difficult situation to explain. Have a service process that starts 2 threads, each thread loops forever but sleeps for 5 minutes each once the payload is finished.
Problem is that my second thread terminates well before the payload is even finished, for no apparent reason, and i also can't catch the exception as it seems to be triggered from outside the delegate process?
Any suggestions on how to find the problem?
The code....
public void StartService()
{
ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
ThreadStart stSend = new ThreadStart(SendNewMail);
senderThread = new Thread(stRecieve);
recieverThread = new Thread(stSend);
sendStarted = true;
recieveStarted = true;
senderThread.Start();
recieverThread.Start();
}
private void DownloadNewMail()
{
while(recieveStarted)
{
//Payload....
if (recieveStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
private void SendNewMail()
{
while(sendStarted)
{
//Payload....
if (sendStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
Try to check callstack lenght in your code:
class Program
{
static void Main(string[] args)
{
try
{
Hop();
}
catch (Exception e)
{
Console.WriteLine("Exception - {0}", e);
}
}
static void Hop()
{
CheckStackTrace();
Hip();
}
static void Hip()
{
CheckStackTrace();
Hop();
}
static void CheckStackTrace()
{
StackTrace s = new StackTrace();
if (s.FrameCount > 50)
throw new Exception("Big stack!!!!");
}
}
If you are having trouble following the flow of your application's code execution, try logging the entrance of methods with a timestamp and threadid.
Also, You can't catch the exception because it is a StackOverflowException.
See msdn: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. "
Do you utlize any heavy-weight library for tasks like DownloadNewMail and SendNewMail? For example I encountered StackOverflows when running large jobs using Microsoft.SqlServer.Dts.Runtime.Package. Try running the same workload sequentially inside a command-line application to see if the issue persists.

Exception handling in threads

Recently i have attended an interview . A code snippet is given to me.I know,the interviewer took it from albhari's threading sample.
public static void Main()
{
try
{
new Thread (Go).Start();
}
catch (Exception ex)
{
// We'll never get here!
Console.WriteLine ("Exception!");
}
}
static void Go() { throw null; }
The modification of the above code as
public static void Main()
{
new Thread (Go).Start();
}
static void Go()
{
try
{
...
throw null; // this exception will get caught below
...
}
catch (Exception ex)
{
Typically log the exception, and/or signal another thread
that we've come unstuck
...
}
}
would be the good candidate to handle the exception.
I have been asked, "Except the above trail what are the other alternatives would fit as good solution?. It was hard to find the alternative,so i raise it here to gather your suggestion.
Exception thrown in a thread normally couldn't be caught in another thread.
You'd better to catch it in function Go and pass it to main thread explicitly.
However, if you just want to log all unhandled messages from all threads, you may use AppDomain.UnhandledException event or equivalent events at Application class if you are developing WinForms or WPF app.
what are the other alternatives would fit as good solution?.
Solution to what? What problem are you trying to solve?
If you use BackgroundWorker, as opposed to Thread, it has an RunWorkerCompleted event, and within that you can check the RunWorkerCompletedEventArgs param for the Error property. This generally is used in WinForms or WPF apps, because there is good support for BackgroundWorker in the Visual Studio designer.
You could also define a delegate for Go(), and call BeginInvoke() on it. Of course you need the EndInvoke() too.
Also, it's generally not a good idea to start up random threads. ThreadPool.QueueUserWorkItem, BackgroundWorker, or asynch delegates all use the ThreadPool, and are recommended.
There are alternatives listed on Joe Albahari's website:
http://www.albahari.com/threading/#_Exception_Handling
"There are, however, some cases where you don’t need to handle exceptions on a worker thread, because the .NET Framework does it for you. These are covered in upcoming sections, and are:
-Asynchronous delegates
-BackgroundWorker
-The Task Parallel Library (conditions apply)"
You can use the AppDomain.UnhandledException event
I think this is the easiest way is:
BackgroundWorker bw = new BackgroundWorker();
bw.DoWork += new DoWorkEventHandler((object sender2, DoWorkEventArgs e2) =>
{
throw new Exception("something bad");
e2.Result = 1 + 1;
});
bw.RunWorkerCompleted += new RunWorkerCompletedEventHandler((object sender2, RunWorkerCompletedEventArgs e2) =>
{
if (e2.Error != null)
{
Console.WriteLine("Error: " + e2.Error.Message);
}
});
bw.RunWorkerAsync();
but there is another way that some might prefer if you want to synchronize the thread (perhaps this is on a thread other than the GUI thread):
private class FileCopier
{
public bool failed = false;
public Exception ex = null;
public string localPath;
public string dstPath;
public FileCopier(string localPath, string dstPath)
{
this.localPath = localPath;
this.dstPath = dstPath;
}
public void Copy()
{
try{
throw new Exception("bad path");
}catch(Exception ex2)
{
ex = ex2;
failed = true;
}
}
}
public static void Main()
{
FileCopier fc = new FileCopier("some path", "some path");
Thread t = new Thread(fc.Copy);
t.Start();
t.Join();
if (fc.failed)
Console.WriteLine(fc.ex.Message);
}
Note that the second example would make more sense if you have several threads and you loop through them and join all...but I kept the example simple.
the 3rd pattern would be using Task Factory which is cleaner:
private static test(){
List<Task<float>> tasks = new List<Task<float>>();
for (float i = -3.0f; i <= 3.0f; i+=1.0f)
{
float num = i;
Console.WriteLine("sent " + i);
Task<float> task = Task.Factory.StartNew<float>(() => Div(5.0f, num));
tasks.Add(task);
}
foreach(Task<float> t in tasks)
{
try
{
t.Wait();
if (t.IsFaulted)
{
Console.WriteLine("Something went wrong: " + t.Exception.Message);
}
else
{
Console.WriteLine("result: " + t.Result);
}
}catch(Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
}
}
}
private static float Div(float a, float b)
{
Console.WriteLine("got " + b);
if (b == 0) throw new Exception("Divide by zero");
return a / b;
}

Categories

Resources