mirror of
https://github.com/JKorf/CryptoExchange.Net
synced 2026-02-16 22:23:54 +00:00
Added timeout/ct task cleanup AsyncResetEvent
This commit is contained in:
parent
40d480e1fc
commit
4a79ce22ec
@ -53,41 +53,57 @@ namespace CryptoExchange.Net.Objects
|
|||||||
_waiters.Enqueue(tcs);
|
_waiters.Enqueue(tcs);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (timeout.HasValue || ct.CanBeCanceled)
|
CancellationTokenSource? delayCts = null;
|
||||||
|
|
||||||
|
try
|
||||||
{
|
{
|
||||||
// Wait for either timeout, cancellation token or set result
|
if (timeout.HasValue || ct.CanBeCanceled)
|
||||||
var delayTask = Task.Delay(timeout ?? Timeout.InfiniteTimeSpan, ct);
|
|
||||||
var completedTask = await Task.WhenAny(tcs.Task, delayTask).ConfigureAwait(false);
|
|
||||||
|
|
||||||
if (completedTask != tcs.Task)
|
|
||||||
{
|
{
|
||||||
// This was a timeout or cancellation, need to remove tcs from waiters
|
delayCts = CancellationTokenSource.CreateLinkedTokenSource(ct);
|
||||||
// if the tcs was set instead it will be removed in the Set method
|
|
||||||
|
|
||||||
if (tcs.TrySetResult(false))
|
var delayTask = Task.Delay(
|
||||||
|
timeout ?? Timeout.InfiniteTimeSpan,
|
||||||
|
delayCts.Token);
|
||||||
|
|
||||||
|
var completedTask =
|
||||||
|
await Task.WhenAny(tcs.Task, delayTask)
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
|
if (completedTask != tcs.Task)
|
||||||
{
|
{
|
||||||
lock (_waitersLock)
|
// This was a timeout or cancellation, need to remove tcs from waiters
|
||||||
|
// if the tcs was set instead it will be removed in the Set method
|
||||||
|
if (tcs.TrySetResult(false))
|
||||||
{
|
{
|
||||||
// Dequeue and put in the back of the queue again except for the one we need to remove
|
lock (_waitersLock)
|
||||||
int count = _waiters.Count;
|
|
||||||
for (int i = 0; i < count; i++)
|
|
||||||
{
|
{
|
||||||
var w = _waiters.Dequeue();
|
// Dequeue and put in the back of the queue again except for the one we need to remove
|
||||||
if (w != tcs)
|
int count = _waiters.Count;
|
||||||
_waiters.Enqueue(w);
|
for (int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
var w = _waiters.Dequeue();
|
||||||
|
if (w != tcs)
|
||||||
|
_waiters.Enqueue(w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
}
|
else
|
||||||
else
|
{
|
||||||
{
|
await tcs.Task.ConfigureAwait(false);
|
||||||
await tcs.Task.ConfigureAwait(false);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
// Actively stop the delay if tcs.Task won
|
||||||
|
delayCts?.Cancel();
|
||||||
|
delayCts?.Dispose();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user