In my previous post, I discussed using ServerSyncProviderProxy with ChannelFactory<T>, and explained how you can get up and running with that combination. While the described modification is definitely necessary, there's at least one other caveat that I've encountered so far.

ChannelFactory<T> implements both ICommunicationObject and IDisposable, and it's necessary to properly close an instance. A ChannelFactory<T> instance and any proxies that it creates are connected, and closing the ChannelFactory<T> instance will also close the proxies. However, that's not true the other way around.

ServerSyncProviderProxy itself implements IDisposable, and it properly disposes of the proxy passed to it, but since it has no knowledge of the ChannelFactory used to create the proxy, it's not going to dispose of that.

This causes the ServerSyncProviderProxy to hang (and ultimately time out) when you try to dispose of it.

Lesson #2

When using proxies created by ChannelFactory<T>.CreateChannel, you must manually ensure that the ChannelFactory is properly disposed when the SyncAgent disposes. Fortunately, that's not very hard to do; it just requires you to hold a reference to it in your derived SyncAgent and create it like this:

this.syncServiceFactory = 
    new ChannelFactory<ISyncService>(binding, serviceAddress.ToString());
ISyncService proxy = this.syncServiceFactory.CreateChannel();
this.RemoteProvider = new ServerSyncProviderProxy(proxy);

Subsequently, you need to ensure that it's being properly disposed together with the SyncAgent itself:

protected override void Dispose(bool disposing)
{
    base.Dispose(disposing);
 
    if (disposing)
    {
        this.syncServiceFactory.Close();
    }
}

This will allow the SyncAgent and, implicitly, the ServerSyncProviderProxy to close immediately.