|
|
@@ -2,7 +2,7 @@
|
|
|
// The .NET Foundation licenses this file to you under the MIT License.
|
|
|
// See the LICENSE file in the project root for more information.
|
|
|
|
|
|
-using System.Collections.Generic;
|
|
|
+using System.IO;
|
|
|
using System.Threading;
|
|
|
|
|
|
namespace System.Reactive
|
|
|
@@ -18,7 +18,7 @@ namespace System.Reactive
|
|
|
/// The singleton instance of the exception indicating a terminal state,
|
|
|
/// DO NOT LEAK or signal this via OnError!
|
|
|
/// </summary>
|
|
|
- public static Exception Terminated { get; } = new TerminatedException();
|
|
|
+ public static Exception Terminated { get; } = new EndOfStreamException("On[Error|Completed]");
|
|
|
|
|
|
/// <summary>
|
|
|
/// Tries to atomically set the Exception on the given field if it is
|
|
|
@@ -31,78 +31,5 @@ namespace System.Reactive
|
|
|
{
|
|
|
return Interlocked.CompareExchange(ref field, ex, null) == null;
|
|
|
}
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Atomically swaps in the Terminated exception into the field and
|
|
|
- /// returns the previous exception in that field (which could be the
|
|
|
- /// Terminated instance too).
|
|
|
- /// </summary>
|
|
|
- /// <param name="field">The target field to terminate.</param>
|
|
|
- /// <returns>The previous exception in that field before the termination.</returns>
|
|
|
- public static Exception Terminate(ref Exception field)
|
|
|
- {
|
|
|
- var current = Volatile.Read(ref field);
|
|
|
- if (current != Terminated)
|
|
|
- {
|
|
|
- current = Interlocked.Exchange(ref field, Terminated);
|
|
|
- }
|
|
|
- return current;
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// Atomically sets the field to the given new exception or combines
|
|
|
- /// it with any pre-existing exception as a new AggregateException
|
|
|
- /// unless the field contains the Terminated instance.
|
|
|
- /// </summary>
|
|
|
- /// <param name="field">The field to set or combine with.</param>
|
|
|
- /// <param name="ex">The exception to combine with.</param>
|
|
|
- /// <returns>True if successful, false if the field contains the Terminated instance.</returns>
|
|
|
- /// <remarks>This type of atomic aggregation helps with operators that
|
|
|
- /// want to delay all errors until all of their sources terminate in some way.</remarks>
|
|
|
- public static bool TryAddException(ref Exception field, Exception ex)
|
|
|
- {
|
|
|
- for (; ; )
|
|
|
- {
|
|
|
- var current = Volatile.Read(ref field);
|
|
|
- if (current == Terminated)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- Exception b;
|
|
|
-
|
|
|
- if (current == null)
|
|
|
- {
|
|
|
- b = ex;
|
|
|
- }
|
|
|
- else if (current is AggregateException a)
|
|
|
- {
|
|
|
- var list = new List<Exception>(a.InnerExceptions)
|
|
|
- {
|
|
|
- ex
|
|
|
- };
|
|
|
- b = new AggregateException(list);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- b = new AggregateException(current, ex);
|
|
|
- }
|
|
|
-
|
|
|
- if (Interlocked.CompareExchange(ref field, b, current) == current)
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /// <summary>
|
|
|
- /// The class indicating a terminal state as an Exception type.
|
|
|
- /// </summary>
|
|
|
- private sealed class TerminatedException : Exception
|
|
|
- {
|
|
|
- internal TerminatedException() : base("No further exceptions")
|
|
|
- {
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
}
|