CloseCollectionAsyncResult.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. //-----------------------------------------------------------------------------
  4. namespace System.ServiceModel
  5. {
  6. using System.Collections.Generic;
  7. using System.Runtime;
  8. using System.Threading;
  9. class CloseCollectionAsyncResult : AsyncResult
  10. {
  11. bool completedSynchronously;
  12. Exception exception;
  13. static AsyncCallback nestedCallback = Fx.ThunkCallback(new AsyncCallback(Callback));
  14. int count;
  15. public CloseCollectionAsyncResult(TimeSpan timeout, AsyncCallback otherCallback, object state, IList<ICommunicationObject> collection)
  16. : base(otherCallback, state)
  17. {
  18. TimeoutHelper timeoutHelper = new TimeoutHelper(timeout);
  19. completedSynchronously = true;
  20. count = collection.Count;
  21. if (count == 0)
  22. {
  23. Complete(true);
  24. return;
  25. }
  26. for (int index = 0; index < collection.Count; index++)
  27. {
  28. CallbackState callbackState = new CallbackState(this, collection[index]);
  29. IAsyncResult result;
  30. try
  31. {
  32. result = collection[index].BeginClose(timeoutHelper.RemainingTime(), nestedCallback, callbackState);
  33. }
  34. #pragma warning suppress 56500 // covered by FxCOP
  35. catch (Exception e)
  36. {
  37. if (Fx.IsFatal(e))
  38. {
  39. throw;
  40. }
  41. Decrement(true, e);
  42. collection[index].Abort();
  43. continue;
  44. }
  45. if (result.CompletedSynchronously)
  46. {
  47. CompleteClose(collection[index], result);
  48. }
  49. }
  50. }
  51. void CompleteClose(ICommunicationObject communicationObject, IAsyncResult result)
  52. {
  53. Exception closeException = null;
  54. try
  55. {
  56. communicationObject.EndClose(result);
  57. }
  58. #pragma warning suppress 56500 // covered by FxCOP
  59. catch (Exception e)
  60. {
  61. if (Fx.IsFatal(e))
  62. {
  63. throw;
  64. }
  65. closeException = e;
  66. communicationObject.Abort();
  67. }
  68. Decrement(result.CompletedSynchronously, closeException);
  69. }
  70. static void Callback(IAsyncResult result)
  71. {
  72. if (result.CompletedSynchronously)
  73. {
  74. return;
  75. }
  76. CallbackState callbackState = (CallbackState)result.AsyncState;
  77. callbackState.Result.CompleteClose(callbackState.Instance, result);
  78. }
  79. void Decrement(bool completedSynchronously)
  80. {
  81. if (completedSynchronously == false)
  82. this.completedSynchronously = false;
  83. if (Interlocked.Decrement(ref count) == 0)
  84. {
  85. if (this.exception != null)
  86. Complete(this.completedSynchronously, this.exception);
  87. else
  88. Complete(this.completedSynchronously);
  89. }
  90. }
  91. void Decrement(bool completedSynchronously, Exception exception)
  92. {
  93. this.exception = exception;
  94. this.Decrement(completedSynchronously);
  95. }
  96. public static void End(IAsyncResult result)
  97. {
  98. AsyncResult.End<CloseCollectionAsyncResult>(result);
  99. }
  100. class CallbackState
  101. {
  102. ICommunicationObject instance;
  103. CloseCollectionAsyncResult result;
  104. public CallbackState(CloseCollectionAsyncResult result, ICommunicationObject instance)
  105. {
  106. this.result = result;
  107. this.instance = instance;
  108. }
  109. public ICommunicationObject Instance
  110. {
  111. get { return instance; }
  112. }
  113. public CloseCollectionAsyncResult Result
  114. {
  115. get { return result; }
  116. }
  117. }
  118. }
  119. }