c# - WCF using, closing and extensions -
i stumped. perhaps can shed light on wcf client behavior observing.
using wcf samples, i've started playing different approaches wcf client/server communication. while executing 1m of test requests in parallel, using sysinternals tcpview monitor open ports. now, there @ least 4 different ways call client:
- create client, thing, , let gc collect it
- create client in using block, thing
- create client channel factory in using block, thing
- create client or channel, use wcf extensions thing
now, knowledge, options 2-4, explicitly call client.close(). during execution see lot of ports left in time_wait state. i'd expect option 1 worst case scenario, due reliance on gc. however, surprise, seems cleanest of them all, meaning, leaves no lingering ports behind.
what missing?
update: source code
private static void runclientworse(concurrentbag<double> cb) { var client = new calculatorclient(); client.endpoint.address = new endpointaddress("net.tcp://localhost:8000/servicemodelsamples/service"); runclientcommon(cb, client); } private static void runclientbetter(concurrentbag<double> cb) { using (var client = new calculatorclient()) { client.endpoint.address = new endpointaddress("net.tcp://localhost:8000/servicemodelsamples/service"); runclientcommon(cb, client); } } private static void runclientbest(concurrentbag<double> cb) { const string uri = "net.tcp://localhost:8000/servicemodelsamples/service"; var address = new endpointaddress(uri); //var binding = new nettcpbinding("nettcpbinding_icalculator"); using (var factory = new channelfactory<icalculator>("nettcpbinding_icalculator",address)) { icalculator client = factory.createchannel(); ((icontextchannel)client).operationtimeout = timespan.fromseconds(60); runclientcommon(cb, client); } } private static void runclientbestext(concurrentbag<double> cb) { const string uri = "net.tcp://localhost:8000/servicemodelsamples/service"; var address = new endpointaddress(uri); //var binding = new nettcpbinding("nettcpbinding_icalculator"); new channelfactory<icalculator>("nettcpbinding_icalculator", address).using( factory => { icalculator client = factory.createchannel(); ((icontextchannel)client).operationtimeout = timespan.fromseconds(60); runclientcommon(cb, client); }); }
i have figured out, think. gc not call dispose on clientbase. that's why connections not left in time_wait state. decided follow same pattern , created new wcf extension:
public static void usingabort<t>(this t client, action<t> work) t : icommunicationobject { try { work(client); client.abort(); } catch (communicationexception e) { logger.warn(e); client.abort(); } catch (timeoutexception e) { logger.warn(e); client.abort(); } catch (exception e) { logger.warn(e); client.abort(); throw; } } }
this way, @ end of request abort connection instead of closing it.
Comments
Post a Comment