fix: idempotent HistorianSession.DisposeAsync + upfront cancellation check
This commit is contained in:
@@ -13,6 +13,7 @@ public sealed class HistorianSession : IAsyncDisposable
|
|||||||
private readonly HistorianGrpcConnection _connection;
|
private readonly HistorianGrpcConnection _connection;
|
||||||
private readonly HistorianGrpcHandshake.Session _session;
|
private readonly HistorianGrpcHandshake.Session _session;
|
||||||
private readonly HistorianClientOptions _options;
|
private readonly HistorianClientOptions _options;
|
||||||
|
private int _disposed;
|
||||||
|
|
||||||
/// <summary>Whether this session was opened read-only or write-enabled (the Open2 connection mode).</summary>
|
/// <summary>Whether this session was opened read-only or write-enabled (the Open2 connection mode).</summary>
|
||||||
public HistorianSessionKind Kind { get; }
|
public HistorianSessionKind Kind { get; }
|
||||||
@@ -41,6 +42,7 @@ public sealed class HistorianSession : IAsyncDisposable
|
|||||||
int maxValues,
|
int maxValues,
|
||||||
[EnumeratorCancellation] CancellationToken ct = default)
|
[EnumeratorCancellation] CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
var orch = new HistorianGrpcReadOrchestrator(_options);
|
var orch = new HistorianGrpcReadOrchestrator(_options);
|
||||||
IReadOnlyList<HistorianSample> rows = await Task.Run(
|
IReadOnlyList<HistorianSample> rows = await Task.Run(
|
||||||
() => orch.RunRawQueryOnSession(_connection, _session.ClientHandle, tag, startUtc, endUtc, maxValues, ct), ct)
|
() => orch.RunRawQueryOnSession(_connection, _session.ClientHandle, tag, startUtc, endUtc, maxValues, ct), ct)
|
||||||
@@ -63,6 +65,7 @@ public sealed class HistorianSession : IAsyncDisposable
|
|||||||
TimeSpan interval,
|
TimeSpan interval,
|
||||||
[EnumeratorCancellation] CancellationToken ct = default)
|
[EnumeratorCancellation] CancellationToken ct = default)
|
||||||
{
|
{
|
||||||
|
ct.ThrowIfCancellationRequested();
|
||||||
var orch = new HistorianGrpcReadOrchestrator(_options);
|
var orch = new HistorianGrpcReadOrchestrator(_options);
|
||||||
IReadOnlyList<HistorianAggregateSample> rows = await Task.Run(
|
IReadOnlyList<HistorianAggregateSample> rows = await Task.Run(
|
||||||
() => orch.RunAggregateQueryOnSession(_connection, _session.ClientHandle, tag, startUtc, endUtc, mode, interval, ct), ct)
|
() => orch.RunAggregateQueryOnSession(_connection, _session.ClientHandle, tag, startUtc, endUtc, mode, interval, ct), ct)
|
||||||
@@ -179,8 +182,11 @@ public sealed class HistorianSession : IAsyncDisposable
|
|||||||
/// <summary>Disposes the underlying gRPC connection (closes the channel). The server-side session
|
/// <summary>Disposes the underlying gRPC connection (closes the channel). The server-side session
|
||||||
/// also idle-expires on its own; this releases the local channel resources immediately.</summary>
|
/// also idle-expires on its own; this releases the local channel resources immediately.</summary>
|
||||||
public ValueTask DisposeAsync()
|
public ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
if (Interlocked.Exchange(ref _disposed, 1) == 0)
|
||||||
{
|
{
|
||||||
_connection.Dispose();
|
_connection.Dispose();
|
||||||
|
}
|
||||||
return ValueTask.CompletedTask;
|
return ValueTask.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user