ClientBase.cs 56 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel
  5. {
  6. using System.ComponentModel;
  7. using System.Diagnostics;
  8. using System.Runtime;
  9. using System.ServiceModel.Channels;
  10. using System.ServiceModel.Description;
  11. using System.ServiceModel.Diagnostics;
  12. using System.Threading;
  13. using System.ServiceModel.Diagnostics.Application;
  14. using System.Runtime.Remoting.Messaging;
  15. using System.ServiceModel.Dispatcher;
  16. using System.Security;
  17. public abstract class ClientBase<TChannel> : ICommunicationObject, IDisposable
  18. where TChannel : class
  19. {
  20. TChannel channel;
  21. ChannelFactoryRef<TChannel> channelFactoryRef;
  22. EndpointTrait<TChannel> endpointTrait;
  23. // Determine whether the proxy can share factory with others. It is false only if the public getters
  24. // are invoked.
  25. bool canShareFactory = true;
  26. // Determine whether the proxy is currently holding a cached factory
  27. bool useCachedFactory;
  28. // Determine whether we have locked down sharing for this proxy. This is turned on only when the channel
  29. // is created.
  30. bool sharingFinalized;
  31. // Determine whether the ChannelFactoryRef has been released. We should release it only once per proxy
  32. bool channelFactoryRefReleased;
  33. // Determine whether we have released the last ref count of the ChannelFactory so that we could abort it when it was closing.
  34. bool releasedLastRef;
  35. object syncRoot = new object();
  36. object finalizeLock = new object();
  37. // Cache at most 32 ChannelFactories
  38. const int maxNumChannelFactories = 32;
  39. static ChannelFactoryRefCache<TChannel> factoryRefCache = new ChannelFactoryRefCache<TChannel>(maxNumChannelFactories);
  40. static object staticLock = new object();
  41. static object cacheLock = new object();
  42. static CacheSetting cacheSetting = CacheSetting.Default;
  43. static bool isCacheSettingReadOnly;
  44. static AsyncCallback onAsyncCallCompleted = Fx.ThunkCallback(new AsyncCallback(OnAsyncCallCompleted));
  45. // IMPORTANT: any changes to the set of protected .ctors of this class need to be reflected
  46. // in ServiceContractGenerator.cs as well.
  47. protected ClientBase()
  48. {
  49. MakeCacheSettingReadOnly();
  50. if (cacheSetting == CacheSetting.AlwaysOff)
  51. {
  52. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>("*"));
  53. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  54. TryDisableSharing();
  55. }
  56. else
  57. {
  58. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>("*", null, null);
  59. InitializeChannelFactoryRef();
  60. }
  61. }
  62. protected ClientBase(string endpointConfigurationName)
  63. {
  64. if (endpointConfigurationName == null)
  65. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  66. MakeCacheSettingReadOnly();
  67. if (cacheSetting == CacheSetting.AlwaysOff)
  68. {
  69. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>(endpointConfigurationName));
  70. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  71. TryDisableSharing();
  72. }
  73. else
  74. {
  75. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, null, null);
  76. InitializeChannelFactoryRef();
  77. }
  78. }
  79. protected ClientBase(string endpointConfigurationName, string remoteAddress)
  80. {
  81. if (endpointConfigurationName == null)
  82. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  83. if (remoteAddress == null)
  84. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  85. MakeCacheSettingReadOnly();
  86. EndpointAddress endpointAddress = new EndpointAddress(remoteAddress);
  87. if (cacheSetting == CacheSetting.AlwaysOff)
  88. {
  89. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>(endpointConfigurationName, endpointAddress));
  90. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  91. TryDisableSharing();
  92. }
  93. else
  94. {
  95. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, endpointAddress, null);
  96. InitializeChannelFactoryRef();
  97. }
  98. }
  99. protected ClientBase(string endpointConfigurationName, EndpointAddress remoteAddress)
  100. {
  101. if (endpointConfigurationName == null)
  102. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  103. if (remoteAddress == null)
  104. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  105. MakeCacheSettingReadOnly();
  106. if (cacheSetting == CacheSetting.AlwaysOff)
  107. {
  108. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>(endpointConfigurationName, remoteAddress));
  109. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  110. TryDisableSharing();
  111. }
  112. else
  113. {
  114. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, remoteAddress, null);
  115. InitializeChannelFactoryRef();
  116. }
  117. }
  118. protected ClientBase(Binding binding, EndpointAddress remoteAddress)
  119. {
  120. if (binding == null)
  121. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
  122. if (remoteAddress == null)
  123. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  124. MakeCacheSettingReadOnly();
  125. if (cacheSetting == CacheSetting.AlwaysOn)
  126. {
  127. this.endpointTrait = new ProgrammaticEndpointTrait<TChannel>(binding, remoteAddress, null);
  128. InitializeChannelFactoryRef();
  129. }
  130. else
  131. {
  132. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>(binding, remoteAddress));
  133. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  134. TryDisableSharing();
  135. }
  136. }
  137. protected ClientBase(ServiceEndpoint endpoint)
  138. {
  139. if (endpoint == null)
  140. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
  141. MakeCacheSettingReadOnly();
  142. if (cacheSetting == CacheSetting.AlwaysOn)
  143. {
  144. this.endpointTrait = new ServiceEndpointTrait<TChannel>(endpoint, null);
  145. this.InitializeChannelFactoryRef();
  146. }
  147. else
  148. {
  149. channelFactoryRef = new ChannelFactoryRef<TChannel>(new ChannelFactory<TChannel>(endpoint));
  150. channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  151. TryDisableSharing();
  152. }
  153. }
  154. protected ClientBase(InstanceContext callbackInstance)
  155. {
  156. if (callbackInstance == null)
  157. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  158. MakeCacheSettingReadOnly();
  159. if (cacheSetting == CacheSetting.AlwaysOff)
  160. {
  161. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  162. new DuplexChannelFactory<TChannel>(callbackInstance, "*"));
  163. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  164. TryDisableSharing();
  165. }
  166. else
  167. {
  168. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>("*", null, callbackInstance);
  169. InitializeChannelFactoryRef();
  170. }
  171. }
  172. protected ClientBase(InstanceContext callbackInstance, string endpointConfigurationName)
  173. {
  174. if (callbackInstance == null)
  175. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  176. if (endpointConfigurationName == null)
  177. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  178. MakeCacheSettingReadOnly();
  179. if (cacheSetting == CacheSetting.AlwaysOff)
  180. {
  181. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  182. new DuplexChannelFactory<TChannel>(callbackInstance, endpointConfigurationName));
  183. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  184. TryDisableSharing();
  185. }
  186. else
  187. {
  188. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, null, callbackInstance);
  189. InitializeChannelFactoryRef();
  190. }
  191. }
  192. protected ClientBase(InstanceContext callbackInstance, string endpointConfigurationName, string remoteAddress)
  193. {
  194. if (callbackInstance == null)
  195. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  196. if (endpointConfigurationName == null)
  197. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  198. if (remoteAddress == null)
  199. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  200. MakeCacheSettingReadOnly();
  201. EndpointAddress endpointAddress = new EndpointAddress(remoteAddress);
  202. if (cacheSetting == CacheSetting.AlwaysOff)
  203. {
  204. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  205. new DuplexChannelFactory<TChannel>(callbackInstance, endpointConfigurationName, endpointAddress));
  206. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  207. TryDisableSharing();
  208. }
  209. else
  210. {
  211. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, endpointAddress, callbackInstance);
  212. InitializeChannelFactoryRef();
  213. }
  214. }
  215. protected ClientBase(InstanceContext callbackInstance, string endpointConfigurationName, EndpointAddress remoteAddress)
  216. {
  217. if (callbackInstance == null)
  218. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  219. if (endpointConfigurationName == null)
  220. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpointConfigurationName");
  221. if (remoteAddress == null)
  222. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  223. MakeCacheSettingReadOnly();
  224. if (cacheSetting == CacheSetting.AlwaysOff)
  225. {
  226. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  227. new DuplexChannelFactory<TChannel>(callbackInstance, endpointConfigurationName, remoteAddress));
  228. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  229. TryDisableSharing();
  230. }
  231. else
  232. {
  233. this.endpointTrait = new ConfigurationEndpointTrait<TChannel>(endpointConfigurationName, remoteAddress, callbackInstance);
  234. InitializeChannelFactoryRef();
  235. }
  236. }
  237. protected ClientBase(InstanceContext callbackInstance, Binding binding, EndpointAddress remoteAddress)
  238. {
  239. if (callbackInstance == null)
  240. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  241. if (binding == null)
  242. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("binding");
  243. if (remoteAddress == null)
  244. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("remoteAddress");
  245. MakeCacheSettingReadOnly();
  246. if (cacheSetting == CacheSetting.AlwaysOn)
  247. {
  248. this.endpointTrait = new ProgrammaticEndpointTrait<TChannel>(binding, remoteAddress, callbackInstance);
  249. InitializeChannelFactoryRef();
  250. }
  251. else
  252. {
  253. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  254. new DuplexChannelFactory<TChannel>(callbackInstance, binding, remoteAddress));
  255. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  256. TryDisableSharing();
  257. }
  258. }
  259. protected ClientBase(InstanceContext callbackInstance, ServiceEndpoint endpoint)
  260. {
  261. if (callbackInstance == null)
  262. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("callbackInstance");
  263. if (endpoint == null)
  264. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endpoint");
  265. MakeCacheSettingReadOnly();
  266. if (cacheSetting == CacheSetting.AlwaysOn)
  267. {
  268. this.endpointTrait = new ServiceEndpointTrait<TChannel>(endpoint, callbackInstance);
  269. InitializeChannelFactoryRef();
  270. }
  271. else
  272. {
  273. this.channelFactoryRef = new ChannelFactoryRef<TChannel>(
  274. new DuplexChannelFactory<TChannel>(callbackInstance, endpoint));
  275. this.channelFactoryRef.ChannelFactory.TraceOpenAndClose = false;
  276. TryDisableSharing();
  277. }
  278. }
  279. protected T GetDefaultValueForInitialization<T>()
  280. {
  281. return default(T);
  282. }
  283. object ThisLock
  284. {
  285. get
  286. {
  287. return syncRoot;
  288. }
  289. }
  290. protected TChannel Channel
  291. {
  292. get
  293. {
  294. // created on demand, so that Mort can modify .Endpoint before calling methods on the client
  295. if (this.channel == null)
  296. {
  297. lock (ThisLock)
  298. {
  299. if (this.channel == null)
  300. {
  301. using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
  302. {
  303. if (DiagnosticUtility.ShouldUseActivity)
  304. {
  305. ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityOpenClientBase, typeof(TChannel).FullName), ActivityType.OpenClient);
  306. }
  307. if (this.useCachedFactory)
  308. {
  309. try
  310. {
  311. CreateChannelInternal();
  312. }
  313. #pragma warning suppress 56500 // covered by FxCOP
  314. catch (Exception ex)
  315. {
  316. if (this.useCachedFactory &&
  317. (ex is CommunicationException ||
  318. ex is ObjectDisposedException ||
  319. ex is TimeoutException))
  320. {
  321. DiagnosticUtility.TraceHandledException(ex, TraceEventType.Warning);
  322. InvalidateCacheAndCreateChannel();
  323. }
  324. else
  325. {
  326. #pragma warning suppress 56503 // [....], We throw only for unknown exceptions.
  327. throw;
  328. }
  329. }
  330. }
  331. else
  332. {
  333. CreateChannelInternal();
  334. }
  335. }
  336. }
  337. }
  338. }
  339. return channel;
  340. }
  341. }
  342. public static CacheSetting CacheSetting
  343. {
  344. get
  345. {
  346. return cacheSetting;
  347. }
  348. set
  349. {
  350. lock (cacheLock)
  351. {
  352. if (isCacheSettingReadOnly && cacheSetting != value)
  353. {
  354. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxImmutableClientBaseCacheSetting, typeof(TChannel).ToString())));
  355. }
  356. else
  357. {
  358. cacheSetting = value;
  359. }
  360. }
  361. }
  362. }
  363. public ChannelFactory<TChannel> ChannelFactory
  364. {
  365. get
  366. {
  367. if (cacheSetting == CacheSetting.Default)
  368. {
  369. TryDisableSharing();
  370. }
  371. return GetChannelFactory();
  372. }
  373. }
  374. public ClientCredentials ClientCredentials
  375. {
  376. get
  377. {
  378. if (cacheSetting == CacheSetting.Default)
  379. {
  380. TryDisableSharing();
  381. }
  382. return this.ChannelFactory.Credentials;
  383. }
  384. }
  385. public CommunicationState State
  386. {
  387. get
  388. {
  389. IChannel channel = (IChannel)this.channel;
  390. if (channel != null)
  391. {
  392. return channel.State;
  393. }
  394. else
  395. {
  396. // we may have failed to create the channel under open, in which case we our factory wouldn't be open
  397. if (!this.useCachedFactory)
  398. {
  399. return GetChannelFactory().State;
  400. }
  401. else
  402. {
  403. return CommunicationState.Created;
  404. }
  405. }
  406. }
  407. }
  408. public IClientChannel InnerChannel
  409. {
  410. get
  411. {
  412. return (IClientChannel)Channel;
  413. }
  414. }
  415. public ServiceEndpoint Endpoint
  416. {
  417. get
  418. {
  419. if (cacheSetting == CacheSetting.Default)
  420. {
  421. TryDisableSharing();
  422. }
  423. return GetChannelFactory().Endpoint;
  424. }
  425. }
  426. public void Open()
  427. {
  428. ((ICommunicationObject)this).Open(GetChannelFactory().InternalOpenTimeout);
  429. }
  430. public void Abort()
  431. {
  432. IChannel channel = (IChannel)this.channel;
  433. if (channel != null)
  434. {
  435. channel.Abort();
  436. }
  437. if (!channelFactoryRefReleased)
  438. {
  439. lock (staticLock)
  440. {
  441. if (!channelFactoryRefReleased)
  442. {
  443. if (this.channelFactoryRef.Release())
  444. {
  445. this.releasedLastRef = true;
  446. }
  447. channelFactoryRefReleased = true;
  448. }
  449. }
  450. }
  451. // Abort the ChannelFactory if we released the last one. We should be able to abort it when another thread is closing it.
  452. if (this.releasedLastRef)
  453. {
  454. this.channelFactoryRef.Abort();
  455. }
  456. }
  457. public void Close()
  458. {
  459. ((ICommunicationObject)this).Close(GetChannelFactory().InternalCloseTimeout);
  460. }
  461. public void DisplayInitializationUI()
  462. {
  463. ((IClientChannel)this.InnerChannel).DisplayInitializationUI();
  464. }
  465. // This ensures that the cachesetting (on, off or default) cannot be modified by
  466. // another ClientBase instance of matching TChannel after the first instance is created.
  467. void MakeCacheSettingReadOnly()
  468. {
  469. if (isCacheSettingReadOnly)
  470. return;
  471. lock (cacheLock)
  472. {
  473. isCacheSettingReadOnly = true;
  474. }
  475. }
  476. void CreateChannelInternal()
  477. {
  478. try
  479. {
  480. this.channel = this.CreateChannel();
  481. if (this.sharingFinalized)
  482. {
  483. if (this.canShareFactory && !this.useCachedFactory)
  484. {
  485. // It is OK to add ChannelFactory to the cache now.
  486. TryAddChannelFactoryToCache();
  487. }
  488. }
  489. }
  490. finally
  491. {
  492. if (!this.sharingFinalized && cacheSetting == CacheSetting.Default)
  493. {
  494. // this.CreateChannel() is not called. For safety, we disable sharing.
  495. TryDisableSharing();
  496. }
  497. }
  498. }
  499. protected virtual TChannel CreateChannel()
  500. {
  501. if (this.sharingFinalized)
  502. return GetChannelFactory().CreateChannel();
  503. lock (this.finalizeLock)
  504. {
  505. this.sharingFinalized = true;
  506. return GetChannelFactory().CreateChannel();
  507. }
  508. }
  509. void IDisposable.Dispose()
  510. {
  511. this.Close();
  512. }
  513. void ICommunicationObject.Open(TimeSpan timeout)
  514. {
  515. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  516. if (!this.useCachedFactory)
  517. {
  518. GetChannelFactory().Open(timeoutHelper.RemainingTime());
  519. }
  520. this.InnerChannel.Open(timeoutHelper.RemainingTime());
  521. }
  522. void ICommunicationObject.Close(TimeSpan timeout)
  523. {
  524. using (ServiceModelActivity activity = DiagnosticUtility.ShouldUseActivity ? ServiceModelActivity.CreateBoundedActivity() : null)
  525. {
  526. if (DiagnosticUtility.ShouldUseActivity)
  527. {
  528. ServiceModelActivity.Start(activity, SR.GetString(SR.ActivityCloseClientBase, typeof(TChannel).FullName), ActivityType.Close);
  529. }
  530. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  531. if (this.channel != null)
  532. {
  533. InnerChannel.Close(timeoutHelper.RemainingTime());
  534. }
  535. if (!channelFactoryRefReleased)
  536. {
  537. lock (staticLock)
  538. {
  539. if (!channelFactoryRefReleased)
  540. {
  541. if (this.channelFactoryRef.Release())
  542. {
  543. this.releasedLastRef = true;
  544. }
  545. this.channelFactoryRefReleased = true;
  546. }
  547. }
  548. // Close the factory outside of the lock so that we can abort from a different thread.
  549. if (this.releasedLastRef)
  550. {
  551. if (this.useCachedFactory)
  552. {
  553. this.channelFactoryRef.Abort();
  554. }
  555. else
  556. {
  557. this.channelFactoryRef.Close(timeoutHelper.RemainingTime());
  558. }
  559. }
  560. }
  561. }
  562. }
  563. event EventHandler ICommunicationObject.Closed
  564. {
  565. add
  566. {
  567. this.InnerChannel.Closed += value;
  568. }
  569. remove
  570. {
  571. this.InnerChannel.Closed -= value;
  572. }
  573. }
  574. event EventHandler ICommunicationObject.Closing
  575. {
  576. add
  577. {
  578. this.InnerChannel.Closing += value;
  579. }
  580. remove
  581. {
  582. this.InnerChannel.Closing -= value;
  583. }
  584. }
  585. event EventHandler ICommunicationObject.Faulted
  586. {
  587. add
  588. {
  589. this.InnerChannel.Faulted += value;
  590. }
  591. remove
  592. {
  593. this.InnerChannel.Faulted -= value;
  594. }
  595. }
  596. event EventHandler ICommunicationObject.Opened
  597. {
  598. add
  599. {
  600. this.InnerChannel.Opened += value;
  601. }
  602. remove
  603. {
  604. this.InnerChannel.Opened -= value;
  605. }
  606. }
  607. event EventHandler ICommunicationObject.Opening
  608. {
  609. add
  610. {
  611. this.InnerChannel.Opening += value;
  612. }
  613. remove
  614. {
  615. this.InnerChannel.Opening -= value;
  616. }
  617. }
  618. IAsyncResult ICommunicationObject.BeginClose(AsyncCallback callback, object state)
  619. {
  620. return ((ICommunicationObject)this).BeginClose(GetChannelFactory().InternalCloseTimeout, callback, state);
  621. }
  622. IAsyncResult ICommunicationObject.BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  623. {
  624. return new ChainedAsyncResult(timeout, callback, state, BeginChannelClose, EndChannelClose, BeginFactoryClose, EndFactoryClose);
  625. }
  626. void ICommunicationObject.EndClose(IAsyncResult result)
  627. {
  628. ChainedAsyncResult.End(result);
  629. }
  630. IAsyncResult ICommunicationObject.BeginOpen(AsyncCallback callback, object state)
  631. {
  632. return ((ICommunicationObject)this).BeginOpen(GetChannelFactory().InternalOpenTimeout, callback, state);
  633. }
  634. IAsyncResult ICommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  635. {
  636. return new ChainedAsyncResult(timeout, callback, state, BeginFactoryOpen, EndFactoryOpen, BeginChannelOpen, EndChannelOpen);
  637. }
  638. void ICommunicationObject.EndOpen(IAsyncResult result)
  639. {
  640. ChainedAsyncResult.End(result);
  641. }
  642. //ChainedAsyncResult methods for opening and closing ChannelFactory<T>
  643. internal IAsyncResult BeginFactoryOpen(TimeSpan timeout, AsyncCallback callback, object state)
  644. {
  645. if (this.useCachedFactory)
  646. {
  647. return new CompletedAsyncResult(callback, state);
  648. }
  649. else
  650. {
  651. return GetChannelFactory().BeginOpen(timeout, callback, state);
  652. }
  653. }
  654. internal void EndFactoryOpen(IAsyncResult result)
  655. {
  656. if (this.useCachedFactory)
  657. {
  658. CompletedAsyncResult.End(result);
  659. }
  660. else
  661. {
  662. GetChannelFactory().EndOpen(result);
  663. }
  664. }
  665. internal IAsyncResult BeginChannelOpen(TimeSpan timeout, AsyncCallback callback, object state)
  666. {
  667. return this.InnerChannel.BeginOpen(timeout, callback, state);
  668. }
  669. internal void EndChannelOpen(IAsyncResult result)
  670. {
  671. this.InnerChannel.EndOpen(result);
  672. }
  673. internal IAsyncResult BeginFactoryClose(TimeSpan timeout, AsyncCallback callback, object state)
  674. {
  675. if (this.useCachedFactory)
  676. {
  677. return new CompletedAsyncResult(callback, state);
  678. }
  679. else
  680. {
  681. return GetChannelFactory().BeginClose(timeout, callback, state);
  682. }
  683. }
  684. internal void EndFactoryClose(IAsyncResult result)
  685. {
  686. if (typeof(CompletedAsyncResult).IsAssignableFrom(result.GetType()))
  687. {
  688. CompletedAsyncResult.End(result);
  689. }
  690. else
  691. {
  692. GetChannelFactory().EndClose(result);
  693. }
  694. }
  695. internal IAsyncResult BeginChannelClose(TimeSpan timeout, AsyncCallback callback, object state)
  696. {
  697. if (this.channel != null)
  698. {
  699. return this.InnerChannel.BeginClose(timeout, callback, state);
  700. }
  701. else
  702. {
  703. return new CompletedAsyncResult(callback, state);
  704. }
  705. }
  706. internal void EndChannelClose(IAsyncResult result)
  707. {
  708. if (typeof(CompletedAsyncResult).IsAssignableFrom(result.GetType()))
  709. {
  710. CompletedAsyncResult.End(result);
  711. }
  712. else
  713. {
  714. this.InnerChannel.EndClose(result);
  715. }
  716. }
  717. ChannelFactory<TChannel> GetChannelFactory()
  718. {
  719. return this.channelFactoryRef.ChannelFactory;
  720. }
  721. void InitializeChannelFactoryRef()
  722. {
  723. Fx.Assert(this.channelFactoryRef == null, "The channelFactory should have never been assigned");
  724. Fx.Assert(this.canShareFactory, "GetChannelFactoryFromCache can be called only when canShareFactory is true");
  725. lock (staticLock)
  726. {
  727. ChannelFactoryRef<TChannel> factoryRef;
  728. if (factoryRefCache.TryGetValue(this.endpointTrait, out factoryRef))
  729. {
  730. if (factoryRef.ChannelFactory.State != CommunicationState.Opened)
  731. {
  732. // Remove the bad ChannelFactory.
  733. factoryRefCache.Remove(this.endpointTrait);
  734. }
  735. else
  736. {
  737. this.channelFactoryRef = factoryRef;
  738. this.channelFactoryRef.AddRef();
  739. useCachedFactory = true;
  740. if (TD.ClientBaseChannelFactoryCacheHitIsEnabled())
  741. {
  742. TD.ClientBaseChannelFactoryCacheHit(this);
  743. }
  744. return;
  745. }
  746. }
  747. }
  748. if (this.channelFactoryRef == null)
  749. {
  750. // Creating the ChannelFactory at initial time to catch configuration exception earlier.
  751. this.channelFactoryRef = CreateChannelFactoryRef(this.endpointTrait);
  752. }
  753. }
  754. static ChannelFactoryRef<TChannel> CreateChannelFactoryRef(EndpointTrait<TChannel> endpointTrait)
  755. {
  756. Fx.Assert(endpointTrait != null, "The endpointTrait should not be null when the factory can be shared.");
  757. ChannelFactory<TChannel> channelFactory = endpointTrait.CreateChannelFactory();
  758. channelFactory.TraceOpenAndClose = false;
  759. return new ChannelFactoryRef<TChannel>(channelFactory);
  760. }
  761. // Once the channel is created, we can't disable caching.
  762. // This method can be called safely multiple times.
  763. // this.sharingFinalized is set the first time the method is called.
  764. // Subsequent calls are essentially no-ops.
  765. void TryDisableSharing()
  766. {
  767. if (this.sharingFinalized)
  768. return;
  769. lock (this.finalizeLock)
  770. {
  771. if (this.sharingFinalized)
  772. return;
  773. this.canShareFactory = false;
  774. this.sharingFinalized = true;
  775. if (this.useCachedFactory)
  776. {
  777. ChannelFactoryRef<TChannel> pendingFactoryRef = this.channelFactoryRef;
  778. this.channelFactoryRef = CreateChannelFactoryRef(this.endpointTrait);
  779. this.useCachedFactory = false;
  780. lock (staticLock)
  781. {
  782. if (!pendingFactoryRef.Release())
  783. {
  784. pendingFactoryRef = null;
  785. }
  786. }
  787. if (pendingFactoryRef != null)
  788. pendingFactoryRef.Abort();
  789. }
  790. }
  791. // can be done outside the lock since the lines below do not access shared data.
  792. // also the use of this.sharingFinalized in the lines above ensures that tracing
  793. // happens only once and only when needed.
  794. if (TD.ClientBaseUsingLocalChannelFactoryIsEnabled())
  795. {
  796. TD.ClientBaseUsingLocalChannelFactory(this);
  797. }
  798. }
  799. void TryAddChannelFactoryToCache()
  800. {
  801. Fx.Assert(this.canShareFactory, "This should be called only when this proxy can share ChannelFactory.");
  802. Fx.Assert(this.channelFactoryRef.ChannelFactory.State == CommunicationState.Opened,
  803. "The ChannelFactory must be in Opened state for caching.");
  804. // Lock the cache and add the item to synchronize with lookup.
  805. lock (staticLock)
  806. {
  807. ChannelFactoryRef<TChannel> cfRef;
  808. if (!factoryRefCache.TryGetValue(this.endpointTrait, out cfRef))
  809. {
  810. // Increment the ref count before adding to the cache.
  811. this.channelFactoryRef.AddRef();
  812. factoryRefCache.Add(this.endpointTrait, this.channelFactoryRef);
  813. this.useCachedFactory = true;
  814. if (TD.ClientBaseCachedChannelFactoryCountIsEnabled())
  815. {
  816. TD.ClientBaseCachedChannelFactoryCount(factoryRefCache.Count, maxNumChannelFactories, this);
  817. }
  818. }
  819. }
  820. }
  821. // NOTE: This should be called inside ThisLock
  822. void InvalidateCacheAndCreateChannel()
  823. {
  824. RemoveFactoryFromCache();
  825. TryDisableSharing();
  826. CreateChannelInternal();
  827. }
  828. void RemoveFactoryFromCache()
  829. {
  830. lock (staticLock)
  831. {
  832. ChannelFactoryRef<TChannel> factoryRef;
  833. if (factoryRefCache.TryGetValue(this.endpointTrait, out factoryRef))
  834. {
  835. if (object.ReferenceEquals(this.channelFactoryRef, factoryRef))
  836. {
  837. factoryRefCache.Remove(this.endpointTrait);
  838. }
  839. }
  840. }
  841. }
  842. // WARNING: changes in the signature/name of the following delegates must be applied to the
  843. // ClientClassGenerator.cs as well, otherwise the ClientClassGenerator would generate wrong code.
  844. protected delegate IAsyncResult BeginOperationDelegate(object[] inValues, AsyncCallback asyncCallback, object state);
  845. protected delegate object[] EndOperationDelegate(IAsyncResult result);
  846. // WARNING: Any changes in the signature/name of the following type and its ctor must be applied to the
  847. // ClientClassGenerator.cs as well, otherwise the ClientClassGenerator would generate wrong code.
  848. protected class InvokeAsyncCompletedEventArgs : AsyncCompletedEventArgs
  849. {
  850. object[] results;
  851. internal InvokeAsyncCompletedEventArgs(object[] results, Exception error, bool cancelled, object userState)
  852. : base(error, cancelled, userState)
  853. {
  854. this.results = results;
  855. }
  856. public object[] Results
  857. {
  858. get
  859. {
  860. return this.results;
  861. }
  862. }
  863. }
  864. // WARNING: Any changes in the signature/name of the following method ctor must be applied to the
  865. // ClientClassGenerator.cs as well, otherwise the ClientClassGenerator would generate wrong code.
  866. protected void InvokeAsync(BeginOperationDelegate beginOperationDelegate, object[] inValues,
  867. EndOperationDelegate endOperationDelegate, SendOrPostCallback operationCompletedCallback, object userState)
  868. {
  869. if (beginOperationDelegate == null)
  870. {
  871. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("beginOperationDelegate");
  872. }
  873. if (endOperationDelegate == null)
  874. {
  875. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("endOperationDelegate");
  876. }
  877. AsyncOperation asyncOperation = AsyncOperationManager.CreateOperation(userState);
  878. AsyncOperationContext context = new AsyncOperationContext(asyncOperation, endOperationDelegate, operationCompletedCallback);
  879. Exception error = null;
  880. object[] results = null;
  881. IAsyncResult result = null;
  882. try
  883. {
  884. result = beginOperationDelegate(inValues, onAsyncCallCompleted, context);
  885. if (result.CompletedSynchronously)
  886. {
  887. results = endOperationDelegate(result);
  888. }
  889. }
  890. catch (Exception e)
  891. {
  892. if (Fx.IsFatal(e))
  893. {
  894. throw;
  895. }
  896. error = e;
  897. }
  898. if (error != null || result.CompletedSynchronously) /* result cannot be null if error == null */
  899. {
  900. CompleteAsyncCall(context, results, error);
  901. }
  902. }
  903. static void OnAsyncCallCompleted(IAsyncResult result)
  904. {
  905. if (result.CompletedSynchronously)
  906. {
  907. return;
  908. }
  909. AsyncOperationContext context = (AsyncOperationContext)result.AsyncState;
  910. Exception error = null;
  911. object[] results = null;
  912. try
  913. {
  914. results = context.EndDelegate(result);
  915. }
  916. catch (Exception e)
  917. {
  918. if (Fx.IsFatal(e))
  919. {
  920. throw;
  921. }
  922. error = e;
  923. }
  924. CompleteAsyncCall(context, results, error);
  925. }
  926. static void CompleteAsyncCall(AsyncOperationContext context, object[] results, Exception error)
  927. {
  928. if (context.CompletionCallback != null)
  929. {
  930. InvokeAsyncCompletedEventArgs e = new InvokeAsyncCompletedEventArgs(results, error, false, context.AsyncOperation.UserSuppliedState);
  931. context.AsyncOperation.PostOperationCompleted(context.CompletionCallback, e);
  932. }
  933. else
  934. {
  935. context.AsyncOperation.OperationCompleted();
  936. }
  937. }
  938. class AsyncOperationContext
  939. {
  940. AsyncOperation asyncOperation;
  941. EndOperationDelegate endDelegate;
  942. SendOrPostCallback completionCallback;
  943. internal AsyncOperationContext(AsyncOperation asyncOperation, EndOperationDelegate endDelegate, SendOrPostCallback completionCallback)
  944. {
  945. this.asyncOperation = asyncOperation;
  946. this.endDelegate = endDelegate;
  947. this.completionCallback = completionCallback;
  948. }
  949. internal AsyncOperation AsyncOperation
  950. {
  951. get
  952. {
  953. return this.asyncOperation;
  954. }
  955. }
  956. internal EndOperationDelegate EndDelegate
  957. {
  958. get
  959. {
  960. return this.endDelegate;
  961. }
  962. }
  963. internal SendOrPostCallback CompletionCallback
  964. {
  965. get
  966. {
  967. return this.completionCallback;
  968. }
  969. }
  970. }
  971. protected class ChannelBase<T> : IClientChannel, IOutputChannel, IRequestChannel, IChannelBaseProxy
  972. where T : class
  973. {
  974. ServiceChannel channel;
  975. System.ServiceModel.Dispatcher.ImmutableClientRuntime runtime;
  976. protected ChannelBase(ClientBase<T> client)
  977. {
  978. if (client.Endpoint.Address == null)
  979. {
  980. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.SFxChannelFactoryEndpointAddressUri)));
  981. }
  982. ChannelFactory<T> cf = client.ChannelFactory;
  983. cf.EnsureOpened(); // to prevent the NullReferenceException that is thrown if the ChannelFactory is not open when cf.ServiceChannelFactory is accessed.
  984. this.channel = cf.ServiceChannelFactory.CreateServiceChannel(client.Endpoint.Address, client.Endpoint.Address.Uri);
  985. this.channel.InstanceContext = cf.CallbackInstance;
  986. this.runtime = this.channel.ClientRuntime.GetRuntime();
  987. }
  988. [Fx.Tag.SecurityNote(Critical = "Accesses the critical IMethodCallMessage interface.",
  989. Safe = "The implementation of IMethodCallMessage is local and is created locally as weell; i.e. not passed in from Remoting.")]
  990. [SecuritySafeCritical]
  991. protected IAsyncResult BeginInvoke(string methodName, object[] args, AsyncCallback callback, object state)
  992. {
  993. object[] inArgs = new object[args.Length + 2];
  994. Array.Copy(args, inArgs, args.Length);
  995. inArgs[inArgs.Length - 2] = callback;
  996. inArgs[inArgs.Length - 1] = state;
  997. IMethodCallMessage methodCall = new MethodCallMessage(inArgs);
  998. ProxyOperationRuntime op = GetOperationByName(methodName);
  999. object[] ins = op.MapAsyncBeginInputs(methodCall, out callback, out state);
  1000. return this.channel.BeginCall(op.Action, op.IsOneWay, op, ins, callback, state);
  1001. }
  1002. [Fx.Tag.SecurityNote(Critical = "Accesses the critical IMethodCallMessage interface.",
  1003. Safe = "The implementation of IMethodCallMessage is local and is created locally as weell; i.e. not passed in from Remoting.")]
  1004. [SecuritySafeCritical]
  1005. protected object EndInvoke(string methodName, object[] args, IAsyncResult result)
  1006. {
  1007. object[] inArgs = new object[args.Length + 1];
  1008. Array.Copy(args, inArgs, args.Length);
  1009. inArgs[inArgs.Length - 1] = result;
  1010. IMethodCallMessage methodCall = new MethodCallMessage(inArgs);
  1011. ProxyOperationRuntime op = GetOperationByName(methodName);
  1012. object[] outs;
  1013. op.MapAsyncEndInputs(methodCall, out result, out outs);
  1014. object ret = this.channel.EndCall(op.Action, outs, result);
  1015. object[] retArgs = op.MapAsyncOutputs(methodCall, outs, ref ret);
  1016. if (retArgs != null)
  1017. {
  1018. Fx.Assert(retArgs.Length == inArgs.Length, "retArgs.Length should be equal to inArgs.Length");
  1019. Array.Copy(retArgs, args, args.Length);
  1020. }
  1021. return ret;
  1022. }
  1023. System.ServiceModel.Dispatcher.ProxyOperationRuntime GetOperationByName(string methodName)
  1024. {
  1025. ProxyOperationRuntime op = this.runtime.GetOperationByName(methodName);
  1026. if (op == null)
  1027. {
  1028. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotSupportedException(SR.GetString(SR.SFxMethodNotSupported1, methodName)));
  1029. }
  1030. return op;
  1031. }
  1032. bool IClientChannel.AllowInitializationUI
  1033. {
  1034. get { return ((IClientChannel)this.channel).AllowInitializationUI; }
  1035. set { ((IClientChannel)this.channel).AllowInitializationUI = value; }
  1036. }
  1037. bool IClientChannel.DidInteractiveInitialization
  1038. {
  1039. get { return ((IClientChannel)this.channel).DidInteractiveInitialization; }
  1040. }
  1041. Uri IClientChannel.Via
  1042. {
  1043. get { return ((IClientChannel)this.channel).Via; }
  1044. }
  1045. event EventHandler<UnknownMessageReceivedEventArgs> IClientChannel.UnknownMessageReceived
  1046. {
  1047. add { ((IClientChannel)this.channel).UnknownMessageReceived += value; }
  1048. remove { ((IClientChannel)this.channel).UnknownMessageReceived -= value; }
  1049. }
  1050. void IClientChannel.DisplayInitializationUI()
  1051. {
  1052. ((IClientChannel)this.channel).DisplayInitializationUI();
  1053. }
  1054. IAsyncResult IClientChannel.BeginDisplayInitializationUI(AsyncCallback callback, object state)
  1055. {
  1056. return ((IClientChannel)this.channel).BeginDisplayInitializationUI(callback, state);
  1057. }
  1058. void IClientChannel.EndDisplayInitializationUI(IAsyncResult result)
  1059. {
  1060. ((IClientChannel)this.channel).EndDisplayInitializationUI(result);
  1061. }
  1062. bool IContextChannel.AllowOutputBatching
  1063. {
  1064. get { return ((IContextChannel)this.channel).AllowOutputBatching; }
  1065. set { ((IContextChannel)this.channel).AllowOutputBatching = value; }
  1066. }
  1067. IInputSession IContextChannel.InputSession
  1068. {
  1069. get { return ((IContextChannel)this.channel).InputSession; }
  1070. }
  1071. EndpointAddress IContextChannel.LocalAddress
  1072. {
  1073. get { return ((IContextChannel)this.channel).LocalAddress; }
  1074. }
  1075. TimeSpan IContextChannel.OperationTimeout
  1076. {
  1077. get { return ((IContextChannel)this.channel).OperationTimeout; }
  1078. set { ((IContextChannel)this.channel).OperationTimeout = value; }
  1079. }
  1080. IOutputSession IContextChannel.OutputSession
  1081. {
  1082. get { return ((IContextChannel)this.channel).OutputSession; }
  1083. }
  1084. EndpointAddress IContextChannel.RemoteAddress
  1085. {
  1086. get { return ((IContextChannel)this.channel).RemoteAddress; }
  1087. }
  1088. string IContextChannel.SessionId
  1089. {
  1090. get { return ((IContextChannel)this.channel).SessionId; }
  1091. }
  1092. TProperty IChannel.GetProperty<TProperty>()
  1093. {
  1094. return ((IChannel)this.channel).GetProperty<TProperty>();
  1095. }
  1096. CommunicationState ICommunicationObject.State
  1097. {
  1098. get { return ((ICommunicationObject)this.channel).State; }
  1099. }
  1100. event EventHandler ICommunicationObject.Closed
  1101. {
  1102. add { ((ICommunicationObject)this.channel).Closed += value; }
  1103. remove { ((ICommunicationObject)this.channel).Closed -= value; }
  1104. }
  1105. event EventHandler ICommunicationObject.Closing
  1106. {
  1107. add { ((ICommunicationObject)this.channel).Closing += value; }
  1108. remove { ((ICommunicationObject)this.channel).Closing -= value; }
  1109. }
  1110. event EventHandler ICommunicationObject.Faulted
  1111. {
  1112. add { ((ICommunicationObject)this.channel).Faulted += value; }
  1113. remove { ((ICommunicationObject)this.channel).Faulted -= value; }
  1114. }
  1115. event EventHandler ICommunicationObject.Opened
  1116. {
  1117. add { ((ICommunicationObject)this.channel).Opened += value; }
  1118. remove { ((ICommunicationObject)this.channel).Opened -= value; }
  1119. }
  1120. event EventHandler ICommunicationObject.Opening
  1121. {
  1122. add { ((ICommunicationObject)this.channel).Opening += value; }
  1123. remove { ((ICommunicationObject)this.channel).Opening -= value; }
  1124. }
  1125. void ICommunicationObject.Abort()
  1126. {
  1127. ((ICommunicationObject)this.channel).Abort();
  1128. }
  1129. void ICommunicationObject.Close()
  1130. {
  1131. ((ICommunicationObject)this.channel).Close();
  1132. }
  1133. void ICommunicationObject.Close(TimeSpan timeout)
  1134. {
  1135. ((ICommunicationObject)this.channel).Close(timeout);
  1136. }
  1137. IAsyncResult ICommunicationObject.BeginClose(AsyncCallback callback, object state)
  1138. {
  1139. return ((ICommunicationObject)this.channel).BeginClose(callback, state);
  1140. }
  1141. IAsyncResult ICommunicationObject.BeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  1142. {
  1143. return ((ICommunicationObject)this.channel).BeginClose(timeout, callback, state);
  1144. }
  1145. void ICommunicationObject.EndClose(IAsyncResult result)
  1146. {
  1147. ((ICommunicationObject)this.channel).EndClose(result);
  1148. }
  1149. void ICommunicationObject.Open()
  1150. {
  1151. ((ICommunicationObject)this.channel).Open();
  1152. }
  1153. void ICommunicationObject.Open(TimeSpan timeout)
  1154. {
  1155. ((ICommunicationObject)this.channel).Open(timeout);
  1156. }
  1157. IAsyncResult ICommunicationObject.BeginOpen(AsyncCallback callback, object state)
  1158. {
  1159. return ((ICommunicationObject)this.channel).BeginOpen(callback, state);
  1160. }
  1161. IAsyncResult ICommunicationObject.BeginOpen(TimeSpan timeout, AsyncCallback callback, object state)
  1162. {
  1163. return ((ICommunicationObject)this.channel).BeginOpen(timeout, callback, state);
  1164. }
  1165. void ICommunicationObject.EndOpen(IAsyncResult result)
  1166. {
  1167. ((ICommunicationObject)this.channel).EndOpen(result);
  1168. }
  1169. IExtensionCollection<IContextChannel> IExtensibleObject<IContextChannel>.Extensions
  1170. {
  1171. get { return ((IExtensibleObject<IContextChannel>)this.channel).Extensions; }
  1172. }
  1173. void IDisposable.Dispose()
  1174. {
  1175. ((IDisposable)this.channel).Dispose();
  1176. }
  1177. Uri IOutputChannel.Via
  1178. {
  1179. get { return ((IOutputChannel)this.channel).Via; }
  1180. }
  1181. EndpointAddress IOutputChannel.RemoteAddress
  1182. {
  1183. get { return ((IOutputChannel)this.channel).RemoteAddress; }
  1184. }
  1185. void IOutputChannel.Send(Message message)
  1186. {
  1187. ((IOutputChannel)this.channel).Send(message);
  1188. }
  1189. void IOutputChannel.Send(Message message, TimeSpan timeout)
  1190. {
  1191. ((IOutputChannel)this.channel).Send(message, timeout);
  1192. }
  1193. IAsyncResult IOutputChannel.BeginSend(Message message, AsyncCallback callback, object state)
  1194. {
  1195. return ((IOutputChannel)this.channel).BeginSend(message, callback, state);
  1196. }
  1197. IAsyncResult IOutputChannel.BeginSend(Message message, TimeSpan timeout, AsyncCallback callback, object state)
  1198. {
  1199. return ((IOutputChannel)this.channel).BeginSend(message, timeout, callback, state);
  1200. }
  1201. void IOutputChannel.EndSend(IAsyncResult result)
  1202. {
  1203. ((IOutputChannel)this.channel).EndSend(result);
  1204. }
  1205. Uri IRequestChannel.Via
  1206. {
  1207. get { return ((IRequestChannel)this.channel).Via; }
  1208. }
  1209. EndpointAddress IRequestChannel.RemoteAddress
  1210. {
  1211. get { return ((IRequestChannel)this.channel).RemoteAddress; }
  1212. }
  1213. Message IRequestChannel.Request(Message message)
  1214. {
  1215. return ((IRequestChannel)this.channel).Request(message);
  1216. }
  1217. Message IRequestChannel.Request(Message message, TimeSpan timeout)
  1218. {
  1219. return ((IRequestChannel)this.channel).Request(message, timeout);
  1220. }
  1221. IAsyncResult IRequestChannel.BeginRequest(Message message, AsyncCallback callback, object state)
  1222. {
  1223. return ((IRequestChannel)this.channel).BeginRequest(message, callback, state);
  1224. }
  1225. IAsyncResult IRequestChannel.BeginRequest(Message message, TimeSpan timeout, AsyncCallback callback, object state)
  1226. {
  1227. return ((IRequestChannel)this.channel).BeginRequest(message, timeout, callback, state);
  1228. }
  1229. Message IRequestChannel.EndRequest(IAsyncResult result)
  1230. {
  1231. return ((IRequestChannel)this.channel).EndRequest(result);
  1232. }
  1233. ServiceChannel IChannelBaseProxy.GetServiceChannel()
  1234. {
  1235. return this.channel;
  1236. }
  1237. class MethodCallMessage : IMethodCallMessage
  1238. {
  1239. readonly object[] args;
  1240. public MethodCallMessage(object[] args)
  1241. {
  1242. this.args = args;
  1243. }
  1244. public object[] Args
  1245. {
  1246. get { return this.args; }
  1247. }
  1248. public int ArgCount
  1249. {
  1250. get { return this.args.Length; }
  1251. }
  1252. public LogicalCallContext LogicalCallContext
  1253. {
  1254. get { return null; }
  1255. }
  1256. public object GetInArg(int argNum)
  1257. {
  1258. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1259. }
  1260. public string GetInArgName(int index)
  1261. {
  1262. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1263. }
  1264. public int InArgCount
  1265. {
  1266. get
  1267. {
  1268. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1269. }
  1270. }
  1271. public object[] InArgs
  1272. {
  1273. get { return this.args; }
  1274. }
  1275. public object GetArg(int argNum)
  1276. {
  1277. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1278. }
  1279. public string GetArgName(int index)
  1280. {
  1281. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1282. }
  1283. public bool HasVarArgs
  1284. {
  1285. get
  1286. {
  1287. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1288. }
  1289. }
  1290. public Reflection.MethodBase MethodBase
  1291. {
  1292. get
  1293. {
  1294. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1295. }
  1296. }
  1297. public string MethodName
  1298. {
  1299. get
  1300. {
  1301. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1302. }
  1303. }
  1304. public object MethodSignature
  1305. {
  1306. get
  1307. {
  1308. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1309. }
  1310. }
  1311. public string TypeName
  1312. {
  1313. get
  1314. {
  1315. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1316. }
  1317. }
  1318. public string Uri
  1319. {
  1320. get
  1321. {
  1322. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1323. }
  1324. }
  1325. public Collections.IDictionary Properties
  1326. {
  1327. get
  1328. {
  1329. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new NotImplementedException());
  1330. }
  1331. }
  1332. }
  1333. }
  1334. }
  1335. }