目录
1、Thread.Join(timeout)
2、Task.WhenAny(task,Task.Delay(timeout))
3、WaitAsync(timeout) 需主动取消
4、CancellationTokenSource(timeout)
1、Thread.Join(timeout)
var thread = new Thread(() =>
{try {Console.WriteLine("Foo start...");Thread.Sleep(5000);Console.WriteLine("Foo end...");} catch{Console.WriteLine("Foo Interrupted...");}});
thread.Start();
if (!thread.Join(1000))
{thread.Interrupt();
}
Console.WriteLine("Done.");
输出:
Hello, World!
Foo start...
Done.
Foo Interrupted...
2、Task.WhenAny(task,Task.Delay(timeout))
Task没有中断方法,只能用取消令牌。
var cts = new CancellationTokenSource();
var task = FooAsync(cts.Token);
var ret = await Task.WhenAny(task, Task.Delay(1000));
if (ret != task)
{cts.Cancel();await task;
}
Console.WriteLine("Done.");async Task FooAsync(CancellationToken token)
{try{Console.WriteLine("Foo start...");await Task.Delay(5000,token);Console.WriteLine("Foo end...");}catch{Console.WriteLine("Foo Interrupted...");}}
输出:
Hello, World!
Foo start...
Foo Interrupted...
Done.
改造成扩展方法:
try
{await FooAsync(CancellationToken.None).TimeoutAfter(TimeSpan.FromSeconds(1));Console.WriteLine("Success!");
}
catch (Exception)
{Console.WriteLine("timeout!");
}
Console.WriteLine("Done.");async Task FooAsync(CancellationToken token)
{try{Console.WriteLine("Foo start...");await Task.Delay(5000,token);Console.WriteLine("Foo end...");}catch{Console.WriteLine("Foo Interrupted...");}}
static class AsyncExtension
{public static async Task TimeoutAfter(this Task task,TimeSpan timeout){using var cts = new CancellationTokenSource();var completedTask = await Task.WhenAny(task,Task.Delay(timeout,cts.Token));if (completedTask != task){cts.Cancel();throw new TimeoutException();}await task;}
}
输出:
Hello, World!
Foo start...
timeout!
Done.
3、WaitAsync(timeout) 需主动取消
需要使用取消令牌,主动取消任务。会抛出超时异常
var cts = new CancellationTokenSource();
try
{await FooAsync(cts.Token).WaitAsync(TimeSpan.FromSeconds(1));Console.WriteLine("Success!");
}
catch (TimeoutException)
{cts.Cancel();Console.WriteLine("timeout!");
}
finally
{cts.Dispose();
}
Console.WriteLine("Done.");async Task FooAsync(CancellationToken token)
{try{Console.WriteLine("Foo start...");await Task.Delay(5000,token);Console.WriteLine("Foo end...");}catch{Console.WriteLine("Foo Interrupted...");}}
输出:
Foo start...
Foo Interrupted...
timeout!
Done.
4、CancellationTokenSource(timeout)
在方法中处理取消异常,不抛出超时异常
var cts = new CancellationTokenSource(TimeSpan.FromSeconds(1));
try
{await FooAsync(cts.Token);Console.WriteLine("Success!");
}
catch (OperationCanceledException)
{cts.Cancel();Console.WriteLine("timeout!");
}
Console.WriteLine("Done.");async Task FooAsync(CancellationToken token)
{try{Console.WriteLine("Foo start...");await Task.Delay(5000,token);Console.WriteLine("Foo end...");}catch(OperationCanceledException){Console.WriteLine("Foo Interrupted...");}}
输出:
Foo start...
Foo Interrupted...
Success!
Done.