I am trying to create an SslStream
object in a new AppDomain
. However, running the BeginAuthenticateAsClient
method on the stream causes an Exception to be thrown.
internal class SslWrapper : MarshalByRefObject
{
public void CreateStream(Stream innerStream)
{
var ioStream = new SslStream(innerStream,
false,
ValidateRemoteCertificate,
SelectLocalCertificate);
ioStream.BeginAuthenticateAsClient("Target",
GetCertificates(),
SslProtocols.Tls,
false,
new AsyncCallback(CallbackMethod),
null);
}
private void CallbackMethod(IAsyncResult result)
{
// TODO: handle callback...
}
}
The exception states:
The type System.Net.AsyncProtocolRequest in Assembly System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 is not marked as serializable.
Edit: The exception is thrown after calling BeginAuthenticateAsClient()
. The SelectLocalCertificate()
callback method is called, but ValidateRemoteCertificate()
is not.
The new AppDomain
and SslWrapper
are created as follows:
_appDomain = AppDomain.CreateDomain(name, null, new AppDomainSetup { PrivateBinPath = pathToDll });
_wrapper = (SslWrapper)_appDomain.CreateInstanceFromAndUnwrap(pathToDll, typeof(SslWrapper).FullName);
_wrapper.CreateStream(innerStream);
Using the synchronous AuthenticateAsClient()
instead works successfully, as does running the asynchronous code in the default AppDomain
.
I assume the exception is related to the AsyncCallback method. However, this method should not be crossing the AppDomain boundary, so why might I be getting the exception? More importantly, is it possible to avoid it?
I am using .NET 2, WinXP 64bit.
Edit: This is also a problem in .NET 4.
the problem should be in your innerStream object, it has to be serializable or MarshalByRefObject in order to work(i.e. be able to be passed as parameter across AppDomain boundary)