TaskCanceledException:取消或超时?
TaskCanceledException: Cancel or timeout?
我只想使用 CancellationTokenSource 进行超时和取消处理。
如何区分TaskCanceledException是超时还是手动取消?
这是一个简化的例子。在实际程序中,我既不知道是否使用了 CancellationTokenSource .CancelAfter() 也不知道是否有人调用 CancellationTokenSource.Cancel()
static CancellationTokenSource cts = new CancellationTokenSource();
static void Main(string[] args)
{
Task.Run(async () =>
{
try
{
await SomeClass.DoSomething(cts.Token);
}
catch (TaskCanceledException ex)
{
//How to find out if the exception occured due to timeout or a call to cts.Cancel()
}
});
while (true)
{
Thread.Sleep(100);
if (someCondition)
cts.Cancel();
}
}
public class SomeClass
{
public static async Task DoSomething(CancellationToken ct)
{
using (var innerCts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
innerCts.CancelAfter(1000);
//Simulate some operation
await Task.Delay(10000, innerCts.Token);
}
}
}
谢谢
汤姆
据我所知,这是最常用的模式:
Task.Run(async () =>
{
try
{
await SomeClass.DoSomething(cts.Token);
}
catch (OperationCanceledException) when (cts.IsCancellationRequested)
{
// cts cancellation occurred
}
catch (OperationCanceledException)
{
// Timeout occurred
}
});
另一个想法是更改 SomeClass.DoSomething
方法的实现,假设您被允许这样做,以便在超时的情况下抛出 TimeoutException
而不是 OperationCanceledException
.
public static async Task DoSomething(CancellationToken cancellationToken)
{
using var innerCts = new CancellationTokenSource(millisecondsDelay: 1000);
using var linkedCts = CancellationTokenSource
.CreateLinkedTokenSource(cancellationToken, innerCts.Token);
try
{
// Simulate some operation
await Task.Delay(10000, linkedCts.Token);
}
catch (OperationCanceledException) when (innerCts.IsCancellationRequested)
{
throw new TimeoutException();
}
}
我只想使用 CancellationTokenSource 进行超时和取消处理。
如何区分TaskCanceledException是超时还是手动取消?
这是一个简化的例子。在实际程序中,我既不知道是否使用了 CancellationTokenSource .CancelAfter() 也不知道是否有人调用 CancellationTokenSource.Cancel()
static CancellationTokenSource cts = new CancellationTokenSource();
static void Main(string[] args)
{
Task.Run(async () =>
{
try
{
await SomeClass.DoSomething(cts.Token);
}
catch (TaskCanceledException ex)
{
//How to find out if the exception occured due to timeout or a call to cts.Cancel()
}
});
while (true)
{
Thread.Sleep(100);
if (someCondition)
cts.Cancel();
}
}
public class SomeClass
{
public static async Task DoSomething(CancellationToken ct)
{
using (var innerCts = CancellationTokenSource.CreateLinkedTokenSource(ct))
{
innerCts.CancelAfter(1000);
//Simulate some operation
await Task.Delay(10000, innerCts.Token);
}
}
}
谢谢
汤姆
据我所知,这是最常用的模式:
Task.Run(async () =>
{
try
{
await SomeClass.DoSomething(cts.Token);
}
catch (OperationCanceledException) when (cts.IsCancellationRequested)
{
// cts cancellation occurred
}
catch (OperationCanceledException)
{
// Timeout occurred
}
});
另一个想法是更改 SomeClass.DoSomething
方法的实现,假设您被允许这样做,以便在超时的情况下抛出 TimeoutException
而不是 OperationCanceledException
.
public static async Task DoSomething(CancellationToken cancellationToken)
{
using var innerCts = new CancellationTokenSource(millisecondsDelay: 1000);
using var linkedCts = CancellationTokenSource
.CreateLinkedTokenSource(cancellationToken, innerCts.Token);
try
{
// Simulate some operation
await Task.Delay(10000, linkedCts.Token);
}
catch (OperationCanceledException) when (innerCts.IsCancellationRequested)
{
throw new TimeoutException();
}
}