考慮下面的簡單示例取消NetworkStream.ReadAsync(準備LinqPad推出,需要提升的帳戶):使用的TcpListener
void Main()
{
Go();
Thread.Sleep(100000);
}
async void Go()
{
TcpListener listener = new TcpListener(IPAddress.Any, 6666);
try
{
cts.Token.Register(() => Console.WriteLine("Token was canceled"));
listener.Start();
using(TcpClient client = await listener.AcceptTcpClientAsync()
.ConfigureAwait(false))
using(var cts = new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
var stream=client.GetStream();
var buffer=new byte[64];
try
{
var amtRead = await stream.ReadAsync(buffer,
0,
buffer.Length,
cts.Token);
Console.WriteLine("finished");
}
catch(TaskCanceledException)
{
Console.WriteLine("boom");
}
}
}
finally
{
listener.Stop();
}
}
如果我telnet客戶端連接到localhost:6666
和坐在那裏什麼都不做,持續5秒,爲什麼我看到「令牌被取消」但從未看到「繁榮」(或「完成」)?
這個NetworkStream不會取消取消嗎?
我可以用Task.Delay()
和Task.WhenAny
的組合來解決這個問題,但我更願意按預期工作。
相反,取消下面的例子:
async void Go(CancellationToken ct)
{
using(var cts=new CancellationTokenSource(TimeSpan.FromSeconds(5)))
{
try
{
await Task.Delay(TimeSpan.FromSeconds(10),cts.Token)
.ConfigureAwait(false);
}
catch(TaskCanceledException)
{
Console.WriteLine("boom");
}
}
}
打印 「咚」,如所預期。這是怎麼回事?