OpenCollectionAsyncResult.cs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  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 OpenCollectionAsyncResult : AsyncResult
  10. {
  11. bool completedSynchronously;
  12. Exception exception;
  13. static AsyncCallback nestedCallback = Fx.ThunkCallback(new AsyncCallback(Callback));
  14. int count;
  15. TimeoutHelper timeoutHelper;
  16. public OpenCollectionAsyncResult(TimeSpan timeout, AsyncCallback otherCallback, object state, IList<ICommunicationObject> collection)
  17. : base(otherCallback, state)
  18. {
  19. this.timeoutHelper = new TimeoutHelper(timeout);
  20. completedSynchronously = true;
  21. count = collection.Count;
  22. if (count == 0)
  23. {
  24. Complete(true);
  25. return;
  26. }
  27. for (int index = 0; index < collection.Count; index++)
  28. {
  29. // Throw exception if there was a failure calling EndOpen in the callback (skips remaining items)
  30. if (this.exception != null)
  31. throw DiagnosticUtility.ExceptionUtility.ThrowHelperError(this.exception);
  32. CallbackState callbackState = new CallbackState(this, collection[index]);
  33. IAsyncResult result = collection[index].BeginOpen(this.timeoutHelper.RemainingTime(), nestedCallback, callbackState);
  34. if (result.CompletedSynchronously)
  35. {
  36. collection[index].EndOpen(result);
  37. Decrement(true);
  38. }
  39. }
  40. }
  41. static void Callback(IAsyncResult result)
  42. {
  43. if (result.CompletedSynchronously)
  44. return;
  45. CallbackState callbackState = (CallbackState)result.AsyncState;
  46. try
  47. {
  48. callbackState.Instance.EndOpen(result);
  49. callbackState.Result.Decrement(false);
  50. }
  51. #pragma warning suppress 56500 // covered by FxCOP
  52. catch (Exception e)
  53. {
  54. if (Fx.IsFatal(e))
  55. throw;
  56. callbackState.Result.Decrement(false, e);
  57. }
  58. }
  59. void Decrement(bool completedSynchronously)
  60. {
  61. if (completedSynchronously == false)
  62. this.completedSynchronously = false;
  63. if (Interlocked.Decrement(ref count) == 0)
  64. {
  65. if (this.exception != null)
  66. Complete(this.completedSynchronously, this.exception);
  67. else
  68. Complete(this.completedSynchronously);
  69. }
  70. }
  71. void Decrement(bool completedSynchronously, Exception exception)
  72. {
  73. this.exception = exception;
  74. this.Decrement(completedSynchronously);
  75. }
  76. public static void End(IAsyncResult result)
  77. {
  78. AsyncResult.End<OpenCollectionAsyncResult>(result);
  79. }
  80. class CallbackState
  81. {
  82. ICommunicationObject instance;
  83. OpenCollectionAsyncResult result;
  84. public CallbackState(OpenCollectionAsyncResult result, ICommunicationObject instance)
  85. {
  86. this.result = result;
  87. this.instance = instance;
  88. }
  89. public ICommunicationObject Instance
  90. {
  91. get { return instance; }
  92. }
  93. public OpenCollectionAsyncResult Result
  94. {
  95. get { return result; }
  96. }
  97. }
  98. }
  99. }