[Mono-list] Threading + Exception Handling (2 Questions)

Jonathan Pryor jonpryor@vt.edu
20 Mar 2003 09:45:39 -0500


It sounds like you want to have an exception generated in one thread
appear in another.  I don't think that's possible.  Exceptions are
relative to the thread they're generated from, and deal exclusively with
the thread of that stack.

However, there is a workaround, if I'm understanding you correctly.  You
could hook up the AppDomain.UnhandledException event to your first
thread, which would let you know if an exception was thrown from some
thread in your application and not caught.

In theory, you could use the UnhandledExceptionEventArgs information to
determine the type of the thrown exception, to ensure that you're
trapping the right errors.  Alas, this information appears to be null
for my build of mono (see attached sample program), but that might be
fixed by now.  Anyone else know for sure?

Regardless, your UnhandledException handler can set a variable which the
main thread checks.  If the variable is set, the main thread would throw
an exception, simulating the appearance of the thread moving from one
thread to another.

As for Thread.Abort, it should work as you expect.  Thread.Abort
generates an exception in the specified thread, not the calling thread
(unless they're the same), and that exception will have no effect on the
calling thread.  So Thread.Abort followed by a throw should work.

There is one problem, though.  Thread.Abort isn't implemented for mono
under Windows (it's a pthread under Windows problem; check the
archives), so this may not be an acceptable solution for you.

 - Jon

On Thu, 2003-03-20 at 08:51, Timothy Parez wrote:
> Hello,
>  
> I have class which creates another thread
> now that other tread can throw a custom error, but
> when this error is thrown I want the main thread of the class library
> to receive this exception so that the client application which uses my
> library get's this error and all execution of other code in my class
> library is stopped.
>  
>  //Code executed by the main thread:
>   protected byte[] Query(byte[] sendData)
>   {
>    //Set all values
>    data = sendData;
>  
>    queryThread = new Thread(new ThreadStart(ExecuteQuery));
>             
>    //Start the query
>    queryThread.Start();
>    
>    //Wait for the query to exit
>    if (!queryThread.Join(timeout * 1000))
>    {
>     queryThread.Abort();
>     throw new Exceptions.QueryTimeoutException("Query Timeout: " +
> timeout.ToString() + " seconds");
>    }
>    
>    //Return the response, which is now saved in the local variable
>    return queryResponse;
>   }
>  
> // Code executed by the queryThread
>  private void ExecuteQuery()
>   {
>    UdpClient client = new UdpClient();
>    //Connect to the server and send the query data
>    try
>    {
>     client.Connect(ip,port);
>     client.Send(data,data.Length);
>    }
>    catch (Exception e)
>    {
>     client.Close();
>     throw new Exceptions.InvalidHostException("Unknown host: " +
> ip,e);
>    }
>  
>    //Listen for a response - This is the client side
>    IPEndPoint serverIPEndPoint = new IPEndPoint(IPAddress.Any,0);
>    
>    //Receive the response
>    try
>    {
>     queryResponse = client.Receive(ref serverIPEndPoint);
>    }
>    catch (Exception e)
>    {
>     throw new Exceptions.ConnectionRefusedException("The connection
> was refused by the remote host: " + ip + ":" + port.ToString(),e);
>    }
>    finally
>    {
>     client.Close();
>    }
>   }
>  
> As you can see the ExecuteQuery() function can throw the
> Exceptions.ConnectionRefusedException,
> but my main thread never receives this error, so the execution of the
> code in the main thread does not stop.
> How can I fix this.
>  
> I also have a second question: 
>     queryThread.Abort();
>     throw new Exceptions.QueryTimeoutException("Query Timeout: " +
> timeout.ToString() + " seconds");
> I abort the second thread, will the QueryTimeoutException still be
> thrown ? (I hope so), or will the .Abort() cause an error
> which will prevent from the QueryTimeoutException ever happening, in
> that case how do I abort the second query and still throw the
> QueryTimeoutException ?
>  
>  
> Thnx.
> TP.