How do I asynchronously call a service operation without having a typed service contract on the client?
An untyped contract is one where there is a single input or output parameter of type Message. Using the Message class rather than strong types allows you to reuse the same contract for any arbitrary message format. To make an untyped contract asynchronous, you just need to apply the standard asynchronous pattern to whatever message exchange pattern you want to use with the contract.
Here's an example of applying the asynchronous pattern to a request-reply contract.
public interface IAsyncRequestReply
IAsyncResult BeginRequest(Message message, AsyncCallback callback, object state);
Message EndRequest(IAsyncResult result);
You could define similar contracts for input, output, and duplex message exchange patterns. You can also specify different combinations of session modes, transaction modes, actions, and other messaging features through the service and operation contract attributes. Once you've written the appropriate contract, you can then construct a channel factory as normal to call the service.