AsyncEventArgs.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. // <copyright>
  2. // Copyright (c) Microsoft Corporation. All rights reserved.
  3. // </copyright>
  4. namespace System.Runtime
  5. {
  6. using System.Diagnostics;
  7. [Fx.Tag.SynchronizationPrimitive(Fx.Tag.BlocksUsing.NonBlocking, SupportsAsync = true, ReleaseMethod = "Complete")]
  8. abstract class AsyncEventArgs : IAsyncEventArgs
  9. {
  10. #if DEBUG
  11. StackTrace startStack;
  12. StackTrace completeStack;
  13. #endif
  14. OperationState state;
  15. object asyncState;
  16. AsyncEventArgsCallback callback;
  17. Exception exception;
  18. public Exception Exception
  19. {
  20. get { return this.exception; }
  21. }
  22. public object AsyncState
  23. {
  24. get { return this.asyncState; }
  25. }
  26. OperationState State
  27. {
  28. set
  29. {
  30. switch (value)
  31. {
  32. case OperationState.PendingCompletion:
  33. if (this.state == OperationState.PendingCompletion)
  34. {
  35. throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.AsyncEventArgsCompletionPending(GetType())));
  36. }
  37. #if DEBUG
  38. if (!Fx.FastDebug)
  39. {
  40. this.startStack = new StackTrace();
  41. }
  42. #endif
  43. break;
  44. case OperationState.CompletedAsynchronously:
  45. case OperationState.CompletedSynchronously:
  46. if (this.state != OperationState.PendingCompletion)
  47. {
  48. throw Fx.Exception.AsError(new InvalidOperationException(InternalSR.AsyncEventArgsCompletedTwice(GetType())));
  49. }
  50. #if DEBUG
  51. if (!Fx.FastDebug)
  52. {
  53. this.completeStack = new StackTrace();
  54. }
  55. #endif
  56. break;
  57. }
  58. this.state = value;
  59. }
  60. }
  61. public void Complete(bool completedSynchronously)
  62. {
  63. this.Complete(completedSynchronously, null);
  64. }
  65. public virtual void Complete(bool completedSynchronously, Exception exception)
  66. {
  67. // The callback will be invoked only if completedSynchronously is false.
  68. // It is the responsibility of the caller or callback to throw the exception.
  69. this.exception = exception;
  70. if (completedSynchronously)
  71. {
  72. this.State = OperationState.CompletedSynchronously;
  73. }
  74. else
  75. {
  76. this.State = OperationState.CompletedAsynchronously;
  77. this.callback(this);
  78. }
  79. }
  80. protected void SetAsyncState(AsyncEventArgsCallback callback, object state)
  81. {
  82. if (callback == null)
  83. {
  84. throw Fx.Exception.ArgumentNull("callback");
  85. }
  86. this.State = OperationState.PendingCompletion;
  87. this.asyncState = state;
  88. this.callback = callback;
  89. }
  90. enum OperationState
  91. {
  92. Created,
  93. PendingCompletion,
  94. CompletedSynchronously,
  95. CompletedAsynchronously,
  96. }
  97. }
  98. class AsyncEventArgs<TArgument> : AsyncEventArgs
  99. {
  100. public TArgument Arguments
  101. {
  102. get;
  103. private set;
  104. }
  105. public virtual void Set(AsyncEventArgsCallback callback, TArgument arguments, object state)
  106. {
  107. this.SetAsyncState(callback, state);
  108. this.Arguments = arguments;
  109. }
  110. }
  111. class AsyncEventArgs<TArgument, TResult> : AsyncEventArgs<TArgument>
  112. {
  113. public TResult Result { get; set; }
  114. }
  115. }