Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exception from lambda expressions

Strange one that I don't still get, is this:

Say,

try
{
    stateClient.Socket.BeginSend(messagePrefixed, 0, messagePrefixed.Length,
        SocketFlags.None, ar => stateClient.Socket.EndSend(ar), stateClient);
}
catch (SocketException ex)
{
    // Handle SocketException.
}
catch (ObjectDisposedException ex)
{
    // Handle ObjectDisposedException.
}

I don't understand why lambda expression that returns with ObjectDisposedException is not caught!? I was going deeper into lambdas and I cant understand it. Is it about the scope of lambda? Range Variables? Thread issue? I know lambda has no multi-threading by their nature but as you can see the return comes from another thread which is created by BeginSend. Before converting the implementation into a lambda this was ok when i had an AsyncCallBack method handling the EndSend.

Any help appreciated. Thank you in advance.

like image 313
George Taskos Avatar asked Dec 11 '09 12:12

George Taskos


People also ask

What are the 3 types of exceptions?

There are three types of exception—the checked exception, the error and the runtime exception.

How does lambda expression handle checked exceptions?

The most straightforward way would be to use a try-catch block, wrap the checked exception into an unchecked exception and rethrow it: List<Integer> integers = Arrays. asList(3, 9, 7, 0, 10, 20); integers. forEach(i -> { try { writeToFile(i); } catch (IOException e) { throw new RuntimeException(e); } });

What are the disadvantages of lambda expression?

The big paradox of lambdas is that they are so syntactically simple to write and so tough to understand if you're not used to them. So if you have to quickly determine what the code is doing, the abstraction brought in by lambdas, even as it simplifies the Java syntax, will be hard to understand quickly and easily.

Can lambda expressions be used for all interfaces?

From Java 8 onwards, lambda expressions can be used to represent the instance of a functional interface. A functional interface can have any number of default methods.


1 Answers

You are correct that lamdas have no inherent asynchronicity or multithreading built-in, but Socket.BeginSend does.

What happens is that the try block encapsulates the call to BeginSend. If that call succeeds, no exception is thrown and the enclosing method returns, no matter what happens on other threads.

If an exception happens during the call to BeginSend, your catch blocks will be invoked.

However, the lambda expression is an asynchronous callback, so it's not going to be invoked until later. This happens in a separate callstack on a separate thread, so the try block is not in effect there.

If you want error handling for the callback, you will need to specify it inside the callback itself (that is, inside the lambda).

like image 186
Mark Seemann Avatar answered Sep 28 '22 00:09

Mark Seemann