All communication in Orleans is asynchronous, similar to communication in gRPC, so in .NET world, you're using async/await with methods that return Task/Task<T>/etc. The boundary there is hopefully apparent: async calls can incur IO and have a cost and the 'async' keyword can hopefully make that cost apparent to the developer.
References to grains are represented by interfaces and if the machine you're communicating with fails, the grain will be re-activated on a surviving host the next time you need to call it. In other words, they are location transparent and the application won't get stuck in some failure state when a machine crashes.
I guess there's a lot to be said in regards to the rest of the .NET changes since 2001. There's no more blocking and spinning forever on a sync called from A to B and perhaps fail over is thought of better. Also it seems to architecture is basically forcing the "good path" of every service being instance based and throw away whereas .NET Remoting offered dark, unscaling singleton paths of dark doom.
References to grains are represented by interfaces and if the machine you're communicating with fails, the grain will be re-activated on a surviving host the next time you need to call it. In other words, they are location transparent and the application won't get stuck in some failure state when a machine crashes.