ChannelFactoryBase.cs 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. //------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //------------------------------------------------------------
  4. namespace System.ServiceModel.Channels
  5. {
  6. using System.Runtime;
  7. using System.ServiceModel;
  8. public abstract class ChannelFactoryBase : ChannelManagerBase, IChannelFactory
  9. {
  10. TimeSpan closeTimeout = ServiceDefaults.CloseTimeout;
  11. TimeSpan openTimeout = ServiceDefaults.OpenTimeout;
  12. TimeSpan receiveTimeout = ServiceDefaults.ReceiveTimeout;
  13. TimeSpan sendTimeout = ServiceDefaults.SendTimeout;
  14. protected ChannelFactoryBase()
  15. {
  16. }
  17. protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts)
  18. {
  19. this.InitializeTimeouts(timeouts);
  20. }
  21. protected override TimeSpan DefaultCloseTimeout
  22. {
  23. get { return this.closeTimeout; }
  24. }
  25. protected override TimeSpan DefaultOpenTimeout
  26. {
  27. get { return this.openTimeout; }
  28. }
  29. protected override TimeSpan DefaultReceiveTimeout
  30. {
  31. get { return this.receiveTimeout; }
  32. }
  33. protected override TimeSpan DefaultSendTimeout
  34. {
  35. get { return this.sendTimeout; }
  36. }
  37. public virtual T GetProperty<T>()
  38. where T : class
  39. {
  40. if (typeof(T) == typeof(IChannelFactory))
  41. {
  42. return (T)(object)this;
  43. }
  44. return default(T);
  45. }
  46. protected override void OnAbort()
  47. {
  48. }
  49. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  50. {
  51. return new CompletedAsyncResult(callback, state);
  52. }
  53. protected override void OnClose(TimeSpan timeout)
  54. {
  55. }
  56. protected override void OnEndClose(IAsyncResult result)
  57. {
  58. CompletedAsyncResult.End(result);
  59. }
  60. void InitializeTimeouts(IDefaultCommunicationTimeouts timeouts)
  61. {
  62. if (timeouts != null)
  63. {
  64. this.closeTimeout = timeouts.CloseTimeout;
  65. this.openTimeout = timeouts.OpenTimeout;
  66. this.receiveTimeout = timeouts.ReceiveTimeout;
  67. this.sendTimeout = timeouts.SendTimeout;
  68. }
  69. }
  70. }
  71. public abstract class ChannelFactoryBase<TChannel> : ChannelFactoryBase, IChannelFactory<TChannel>
  72. {
  73. CommunicationObjectManager<IChannel> channels;
  74. protected ChannelFactoryBase()
  75. : this(null)
  76. {
  77. }
  78. protected ChannelFactoryBase(IDefaultCommunicationTimeouts timeouts)
  79. : base(timeouts)
  80. {
  81. this.channels = new CommunicationObjectManager<IChannel>(this.ThisLock);
  82. }
  83. public TChannel CreateChannel(EndpointAddress address)
  84. {
  85. if (address == null)
  86. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
  87. return this.InternalCreateChannel(address, address.Uri);
  88. }
  89. public TChannel CreateChannel(EndpointAddress address, Uri via)
  90. {
  91. if (address == null)
  92. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("address");
  93. if (via == null)
  94. throw DiagnosticUtility.ExceptionUtility.ThrowHelperArgumentNull("via");
  95. return this.InternalCreateChannel(address, via);
  96. }
  97. TChannel InternalCreateChannel(EndpointAddress address, Uri via)
  98. {
  99. this.ValidateCreateChannel();
  100. TChannel channel = this.OnCreateChannel(address, via);
  101. bool success = false;
  102. try
  103. {
  104. this.channels.Add((IChannel)(object)channel);
  105. success = true;
  106. }
  107. finally
  108. {
  109. if (!success)
  110. ((IChannel)(object)channel).Abort();
  111. }
  112. return channel;
  113. }
  114. protected abstract TChannel OnCreateChannel(EndpointAddress address, Uri via);
  115. protected void ValidateCreateChannel()
  116. {
  117. ThrowIfDisposed();
  118. if (this.State != CommunicationState.Opened)
  119. {
  120. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(new InvalidOperationException(SR.GetString(SR.ChannelFactoryCannotBeUsedToCreateChannels, this.GetType().ToString())));
  121. }
  122. }
  123. protected override void OnAbort()
  124. {
  125. IChannel[] currentChannels = this.channels.ToArray();
  126. foreach (IChannel channel in currentChannels)
  127. channel.Abort();
  128. this.channels.Abort();
  129. }
  130. protected override void OnClose(TimeSpan timeout)
  131. {
  132. IChannel[] currentChannels = this.channels.ToArray();
  133. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  134. foreach (IChannel channel in currentChannels)
  135. channel.Close(timeoutHelper.RemainingTime());
  136. this.channels.Close(timeoutHelper.RemainingTime());
  137. }
  138. protected override IAsyncResult OnBeginClose(TimeSpan timeout, AsyncCallback callback, object state)
  139. {
  140. return new ChainedCloseAsyncResult(timeout, callback, state,
  141. this.channels.BeginClose, this.channels.EndClose,
  142. this.channels.ToArray());
  143. }
  144. protected override void OnEndClose(IAsyncResult result)
  145. {
  146. ChainedCloseAsyncResult.End(result);
  147. }
  148. }
  149. }