这个实现完全基于Sinaesthetic的,但增加了CancellationToken
并保持相同的执行线程和上下文;也就是说,根据condition
是否需要在同一线程中计算,将使用Task.Run()
委托给调用者。
此外,注意,如果你不需要抛出TimeoutException
而仅需中断循环,你可能想要使用cts.CancelAfter()
或new CancellationTokenSource(millisecondsDelay)
来代替使用timeoutTask
与Task.Delay
加Task.WhenAny
。
public static class AsyncUtils
{
public static async Task WaitWhileAsync(CancellationToken ct, Func<bool> condition, int pollDelay = 25)
{
try
{
while (condition())
{
await Task.Delay(pollDelay, ct).ConfigureAwait(true);
}
}
catch (TaskCanceledException)
{
}
}
public static async Task WaitUntilAsync(CancellationToken ct, Func<bool> condition, int pollDelay = 25)
{
try
{
while (!condition())
{
await Task.Delay(pollDelay, ct).ConfigureAwait(true);
}
}
catch (TaskCanceledException)
{
}
}
public static async Task WaitWhileAsync(CancellationToken ct, Func<bool> condition, int pollDelay, int timeout)
{
if (ct.IsCancellationRequested)
{
return;
}
using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
Task waitTask = WaitWhileAsync(cts.Token, condition, pollDelay);
Task timeoutTask = Task.Delay(timeout, cts.Token);
Task finishedTask = await Task.WhenAny(waitTask, timeoutTask).ConfigureAwait(true);
if (!ct.IsCancellationRequested)
{
cts.Cancel();
await finishedTask.ConfigureAwait(true);
if (finishedTask == timeoutTask)
{
throw new TimeoutException();
}
}
}
}
public static async Task WaitUntilAsync(CancellationToken ct, Func<bool> condition, int pollDelay, int timeout)
{
if (ct.IsCancellationRequested)
{
return;
}
using (CancellationTokenSource cts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
Task waitTask = WaitUntilAsync(cts.Token, condition, pollDelay);
Task timeoutTask = Task.Delay(timeout, cts.Token);
Task finishedTask = await Task.WhenAny(waitTask, timeoutTask).ConfigureAwait(true);
if (!ct.IsCancellationRequested)
{
cts.Cancel();
await finishedTask.ConfigureAwait(true);
if (finishedTask == timeoutTask)
{
throw new TimeoutException();
}
}
}
}
}
isExcelInteractive()
是一个检查 Excel 是否繁忙的方法。如果 Excel 不处于编辑模式,则返回 true。这是我需要不断检查直到为真的东西,而且没有事件处理程序。 - Keylee