SoapClient.SendRequestResponse is aware of the MessageID in the outgoing request SOAP header and won't complete the call until it receives a message with a RelatesTo value that matches the original MessageID. So if you're crafting a responder/stub you much parse out the MessageID from the request and inject it into the RelatesTo field in the SOAP header of the response.
It's a little odd that it doesn't just return after any valid SOAP message and throw an expection because of the mismatch. Perhaps this is part of the SOAP web services standard. I didn't look into it.
Example:
Request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance/" xmlns:xsd="http://www.w3.org/2001/XMLSchema/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<soap:Header>
<wsa:MessageID soap:mustUnderstand="1">uuid:20E6C5D8-2E0D-48D0-863D-7789D2CA37A2</wsa:MessageID>
...
Response:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsu="http://schemas.xmlsoap.org/ws/2002/07/utility">
<soap:Header>
<wsa:MessageID SOAP-ENV:mustUnderstand="1" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">uuid:bb1cf43050739c45:248138d0:1328e31d4e2:-5cf4</wsa:MessageID>
<wsa:RelatesTo RelationshipType="wsa:Reply" SOAP-ENV:mustUnderstand="1" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">uuid:20E6C5D8-2E0D-48D0-863D-7789D2CA37A2</wsa:RelatesTo>
...
The RelatesTo value is the same as the MessageID value in the request. The MessageID in the response is new and unique because the response message is not the request message.