/// <summary> /// Creates a new <see cref="ConcurrencyControl" /> instance using the specified settings. /// </summary> /// <param name="mode"> /// The logical concurrency control mode for the resulting control. /// </param> /// <param name="blockTimeoutThreshold"> /// The maximum length of time that the resulting control may block a thread before raising an exception, or /// <see cref="Timeout.InfiniteTimeSpan" /> if indefinite thread blocking is permitted. The default value is /// <see cref="Timeout.InfiniteTimeSpan" />. /// </param> /// <returns> /// A new <see cref="ConcurrencyControl" /> instance. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="blockTimeoutThreshold" /> is less than or equal to <see cref="TimeSpan.Zero" /> and is not equal to /// <see cref="Timeout.InfiniteTimeSpan" /> -or- <paramref name="mode" /> is equal to /// <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> public static ConcurrencyControl New(ConcurrencyControlMode mode, TimeSpan blockTimeoutThreshold) { switch (mode.RejectIf().IsEqualToValue(ConcurrencyControlMode.Unspecified).TargetArgument) { case ConcurrencyControlMode.DuplexSemaphore: return(new DuplexSemaphoreControl(blockTimeoutThreshold)); case ConcurrencyControlMode.ProcessorCountSemaphore: return(new ProcessorCountSemaphoreControl(blockTimeoutThreshold)); case ConcurrencyControlMode.SingleThreadLock: return(new SingleThreadLockControl(blockTimeoutThreshold)); case ConcurrencyControlMode.SingleThreadSpinLock: return(new SingleThreadSpinLockControl(blockTimeoutThreshold)); case ConcurrencyControlMode.Unconstrained: return(new UnconstrainedControl()); default: throw new InvalidOperationException($"The specified concurrency control mode, {mode}, is not supported."); } }
private static TimeSpan PerformUsingSolidControl(Action[] operations, ConcurrencyControlMode mode) { var tasks = new Task[operations.Length]; var stopwatch = new Stopwatch(); stopwatch.Start(); try { using (var control = ConcurrencyControl.New(mode)) { for (var i = 0; i < operations.Length; i++) { var operation = operations[i]; tasks[i] = Task.Factory.StartNew(() => { using (var controlToken = control.Enter()) { operation(); } }); } Task.WaitAll(tasks); } } finally { stopwatch.Stop(); } return(stopwatch.Elapsed); }
internal static void OperationLatency_ShouldBeLow(ConcurrencyControlMode mode, Action <Action <Action <Action> > > performUsingPrimitive, Int32 latencyThresholdInTicks) { // Arrange. var operationCount = 30; var iterationCount = 300; var operations = new Action[operationCount]; var sumOfLatenciesPerOperation = TimeSpan.Zero; InitializeOperations(operations); for (var i = 0; i < iterationCount; i++) { // Act. var primitiveControlDuration = PerformUsingPrimitive(operations, performUsingPrimitive); var solidControlDuration = PerformUsingSolidControl(operations, mode); var totalLatency = (solidControlDuration - primitiveControlDuration); var latencyPerOperation = TimeSpan.FromTicks(totalLatency.Ticks / operationCount); sumOfLatenciesPerOperation += latencyPerOperation; } // Assert. var averageLatencyPerOperationInTicks = (sumOfLatenciesPerOperation.Ticks / iterationCount); averageLatencyPerOperationInTicks.Should().BeLessThan(latencyThresholdInTicks); }
internal static void FunctionalLifeSpanTest_ShouldProduceDesiredResults(ConcurrencyControlMode mode) { // Arrange. var operationCount = 30; var operations = new Action[operationCount]; var tasks = new Task[operationCount]; InitializeOperations(operations); // Act. var action = new Action(() => { using (var target = ConcurrencyControl.New(mode)) { for (var i = 0; i < operationCount; i++) { var operation = operations[i]; tasks[i] = Task.Factory.StartNew(() => { using (var controlToken = target.Enter()) { controlToken.IsActive.Should().BeTrue(); operation(); controlToken.Release(); controlToken.IsActive.Should().BeFalse(); } }); } Task.WaitAll(tasks); } }); // Assert. action.Should().NotThrow(); }
/// <summary> /// Initializes a new instance of the <see cref="MessagingClient" /> class. /// </summary> /// <param name="messageSerializationFormat"> /// Gets the format that is used to serialize and deserialize messages. The default value is /// <see cref="SerializationFormat.Binary" />. /// </param> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.ProcessorCountSemaphore" />. /// </param> /// <param name="operationTimeoutThreshold"> /// The maximum length of time for which an operation may block a thread before raising an exception, or /// <see cref="Timeout.InfiniteTimeSpan" /> if indefinite thread blocking is permitted. The default value is /// <see cref="Timeout.InfiniteTimeSpan" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="messageSerializationFormat" /> is equal to <see cref="SerializationFormat.Unspecified" /> -or- /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" /> -or- /// <paramref name="operationTimeoutThreshold" /> is less than or equal to <see cref="TimeSpan.Zero" /> and is not equal to /// <see cref="Timeout.InfiniteTimeSpan" />. /// </exception> protected MessagingClient(SerializationFormat messageSerializationFormat, ConcurrencyControlMode stateControlMode, TimeSpan operationTimeoutThreshold) : base(stateControlMode, operationTimeoutThreshold) { MessageSerializationFormat = messageSerializationFormat.RejectIf().IsEqualToValue(SerializationFormat.Unspecified, nameof(messageSerializationFormat)); }
/// <summary> /// Initializes a new instance of the <see cref="MessagingClient" /> class. /// </summary> /// <param name="messageSerializationFormat"> /// Gets the format that is used to serialize and deserialize messages. The default value is /// <see cref="SerializationFormat.Binary" />. /// </param> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.ProcessorCountSemaphore" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="messageSerializationFormat" /> is equal to <see cref="SerializationFormat.Unspecified" /> -or- /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> protected MessagingClient(SerializationFormat messageSerializationFormat, ConcurrencyControlMode stateControlMode) : this(messageSerializationFormat, stateControlMode, Timeout.InfiniteTimeSpan) { return; }
/// <summary> /// Initializes a new instance of the <see cref="Instrument" /> class. /// </summary> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.SingleThreadLock" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> public SimulatedInstrument(ConcurrencyControlMode stateControlMode) : base(stateControlMode) { NullableIntegerValue = null; }
/// <summary> /// Creates a new <see cref="ConcurrencyControl" /> instance using the specified settings. /// </summary> /// <param name="mode"> /// The logical concurrency control mode for the resulting control. /// </param> /// <returns> /// A new <see cref="ConcurrencyControl" /> instance. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="mode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> public static ConcurrencyControl New(ConcurrencyControlMode mode) => New(mode, Timeout.InfiniteTimeSpan);
/// <summary> /// Initializes a new instance of the <see cref="MessagePublishingClient" /> class. /// </summary> /// <param name="messageSerializationFormat"> /// Gets the format that is used to serialize and deserialize messages. The default value is /// <see cref="SerializationFormat.Binary" />. /// </param> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.ProcessorCountSemaphore" />. /// </param> /// <param name="operationTimeoutThreshold"> /// The maximum length of time for which an operation may block a thread before raising an exception, or /// <see cref="Timeout.InfiniteTimeSpan" /> if indefinite thread blocking is permitted. The default value is /// <see cref="Timeout.InfiniteTimeSpan" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="messageSerializationFormat" /> is equal to <see cref="SerializationFormat.Unspecified" /> -or- /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" /> -or- /// <paramref name="operationTimeoutThreshold" /> is less than or equal to <see cref="TimeSpan.Zero" /> and is not equal to /// <see cref="Timeout.InfiniteTimeSpan" />. /// </exception> protected MessagePublishingClient(SerializationFormat messageSerializationFormat, ConcurrencyControlMode stateControlMode, TimeSpan operationTimeoutThreshold) : base(messageSerializationFormat, stateControlMode, operationTimeoutThreshold) { return; }
/// <summary> /// Initializes a new instance of the <see cref="MessagePublishingClient" /> class. /// </summary> /// <param name="messageSerializationFormat"> /// Gets the format that is used to serialize and deserialize messages. The default value is /// <see cref="SerializationFormat.Binary" />. /// </param> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.ProcessorCountSemaphore" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="messageSerializationFormat" /> is equal to <see cref="SerializationFormat.Unspecified" /> -or- /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> protected MessagePublishingClient(SerializationFormat messageSerializationFormat, ConcurrencyControlMode stateControlMode) : base(messageSerializationFormat, stateControlMode) { return; }
/// <summary> /// Initializes a new instance of the <see cref="AzureServiceBusSubscriptionClient" />. /// </summary> /// <param name="connection"> /// A connection that governs interaction with Azure Service Bus entities. /// </param> /// <param name="messageSerializationFormat"> /// Gets the format that is used to serialize and deserialize messages. The default value is /// <see cref="SerializationFormat.Binary" />. /// </param> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.ProcessorCountSemaphore" />. /// </param> /// <exception cref="ArgumentNullException"> /// <paramref name="connection" /> is <see langword="null" />. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="messageSerializationFormat" /> is equal to <see cref="SerializationFormat.Unspecified" /> -or- /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> public AzureServiceBusSubscriptionClient(ServiceBusConnection connection, SerializationFormat messageSerializationFormat, ConcurrencyControlMode stateControlMode) : base(messageSerializationFormat, stateControlMode) { Connection = connection.RejectIf().IsNull(nameof(connection)).TargetArgument; LazyClientManager = new Lazy <AzureServiceBusClientManager>(CreateClientManager, LazyThreadSafetyMode.ExecutionAndPublication); }
/// <summary> /// Initializes a new instance of the <see cref="Instrument" /> class. /// </summary> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.SingleThreadLock" />. /// </param> /// <param name="stateControlTimeoutThreshold"> /// The maximum length of time that the instrument's state control may block a thread before raising an exception, or /// <see cref="Timeout.InfiniteTimeSpan" /> if indefinite thread blocking is permitted. The default value is /// <see cref="Timeout.InfiniteTimeSpan" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" /> -or- /// <paramref name="stateControlTimeoutThreshold" /> is less than or equal to <see cref="TimeSpan.Zero" /> and is not equal /// to <see cref="Timeout.InfiniteTimeSpan" />. /// </exception> protected Instrument(ConcurrencyControlMode stateControlMode, TimeSpan stateControlTimeoutThreshold) { StateControlMode = stateControlMode.RejectIf().IsEqualToValue(ConcurrencyControlMode.Unspecified, nameof(stateControlMode)); StateControlTimeoutThreshold = (stateControlTimeoutThreshold == Timeout.InfiniteTimeSpan) ? stateControlTimeoutThreshold : stateControlTimeoutThreshold.RejectIf().IsLessThanOrEqualTo(TimeSpan.Zero, nameof(stateControlTimeoutThreshold)); LazyStateControl = new Lazy <IConcurrencyControl>(InitializeStateControl, LazyThreadSafetyMode.ExecutionAndPublication); }
/// <summary> /// Initializes a new instance of the <see cref="Instrument" /> class. /// </summary> /// <param name="stateControlMode"> /// The concurrency control mode that is used to manage state. The default value is /// <see cref="ConcurrencyControlMode.SingleThreadLock" />. /// </param> /// <exception cref="ArgumentOutOfRangeException"> /// <paramref name="stateControlMode" /> is equal to <see cref="ConcurrencyControlMode.Unspecified" />. /// </exception> protected Instrument(ConcurrencyControlMode stateControlMode) : this(stateControlMode, DefaultStateControlTimeoutThreshold) { return; }