C#:CancellationToken 不会取消阻塞方法 [英] C#: CancellationToken doesn't cancel blocking method

查看:45
本文介绍了C#:CancellationToken 不会取消阻塞方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

.NET 4.5.1:看来,我无法使用 CancellationTokenSource 内置超时取消在任务内运行的阻塞方法.

.NET 4.5.1: It appears, I can't cancel a blocking method running inside a task using the CancellationTokenSource built-in timeout.

class Program
{
    static void Main(string[] args)
    {
        var cts = new System.Threading.CancellationTokenSource();

        System.Console.CancelKeyPress += (s, e) =>
        {
            e.Cancel = true;
            cts.Cancel();
        };

        MainAsync(args, cts.Token).Wait();
    }

    // MainAsync from http://stackoverflow.com/questions/9208921/async-on-main-method-of-console-app
    static async Task MainAsync(string[] args, System.Threading.CancellationToken token)
    {
        Console.WriteLine("Starting MainAsync");
        var cts = new System.Threading.CancellationTokenSource(3000);
        var task = Task.Factory.StartNew(() =>
        {
            Console.WriteLine("Starting task...");
            var t = new System.Net.Sockets.TcpClient();
            var buffer = new byte[t.ReceiveBufferSize];
            t.Connect(new System.Net.IPEndPoint(System.Net.IPAddress.Parse("127.0.0.1"), 1337));

            Console.WriteLine("Recieving...");
            t.Client.Receive(buffer);
            Console.WriteLine("Finished Recieving...");

            return true;
        }, cts.Token);

        var success = await task;

        Console.WriteLine("Did the task complete succesfuly?", success);
    }
}

上述简短的、自包含的、正确的示例(我希望它是正确的)的输出是:

The output from the above Short, Self Contained, Correct Example (I hope it's correct) is:

Starting MainAsync
Starting task...
Recieving...

为什么任务不取消,不抛出异常?

Why does the task doesn't cancel, no exception is thrown?

推荐答案

正如我在我的博客中所述,"你一直在那里使用那个 CancellationToken.我不认为这意味着你认为它意味着什么."

As I state on my blog, "You keep using that CancellationToken there. I do not think it means what you think it means."

特别是,传递给 StartNewCancellationToken 只会取消委托的 starting.如果您希望委托本身支持取消,则委托本身必须遵守 CancellationToken.

In particular, the CancellationToken passed to StartNew will only cancel the starting of the delegate. If you want the delegate itself to support cancellation, then the delegate itself will have to observe the CancellationToken.

这篇关于C#:CancellationToken 不会取消阻塞方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆