的CancellationToken和CancellationTokenSource,如何使用它? [英] CancellationToken and CancellationTokenSource-How to use it?

查看:1735
本文介绍了的CancellationToken和CancellationTokenSource,如何使用它?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我havea称为负载UI按钮。它产生一个线程,这又产生一个任务。上有任务等待,并且如果到期任务被取消。负载未禁用按钮,用户可以单击它多次。每次被点击上一个任务时间应canelled。

I havea UI button called Load. It spawns a thread, which in turn spawns a task. There is a wait on the task, and if it expires the task gets cancelled. The Load button is not disabled, and the user can click on it multiple times. Each time it's clicked the previous task should be canelled.

我越来越糊涂,我应该如何使用CancellationTokenSource和这里的CancellationToken。 Beow是code..can请你建议如何使用它和下面的使用是否有什么问题?没有异步请,因为我们现在还没有。

I'm getting confused on how I should use the CancellationTokenSource and CancellationToken here. Beow is the code..can you please suggest how to use it and whether the below usage has any issues? No Async please as we are not there yet.

CancellationTokenSource _source = new CancellationTokenSource();
        public void OnLoad()
        {
            //Does this cancel the previously spawned task?
            _source.Cancel();
            _source.Dispose();
            _source = new CancellationTokenSource();
            var activeToken = _source.Token;
            //Do I need to do the above all the time or is there an efficient way?

            Task.Factory.StartNew(() =>
                {
                    var child = Task.Factory.StartNew(() =>
                        {
                            Thread.Sleep(TimeSpan.FromSeconds(20));
                            activeToken.ThrowIfCancellationRequested();
                        }, activeToken);

                    if (!child.Wait(TimeSpan.FromSeconds(5)))
                    {
                        _source.Cancel();
                    }
                });
        }

注意我要取消任何先前催生任务,每催生任务应该有一个暂停。

Note I need to cancel any previously spawned tasks, and every spawned task should have a timeout.

推荐答案

首先,如果你正在使用Visual Studio 2012+可以添加微软.Bcl.Async包增加对支持异步等先进功能,您的.NET 4.0的项目。

First, if you are using Visual Studio 2012+ you can add the Microsoft.Bcl.Async package to add support for async and other advanced functionality to your .NET 4.0 project.

如果您使用Visual Studio 2010中,您可以使用自带的ParallelExtensionsExtras库 WithTimeout 扩展方法。该方法包装原始任务与TaskCompletionSource并调用 SetCancelled 如果过期的计时器。

If you are using Visual Studio 2010, you can use the WithTimeout extension method that comes with the ParallelExtensionsExtras library. The method wraps the original Task with a TaskCompletionSource and a timer that calls SetCancelled if it expires.

中的代码的>但实际的方法很简单:

The code is here but the actual method is simple:

    /// <summary>Creates a new Task that mirrors the supplied task but that 
    /// will be canceled after the specified timeout.</summary>
    /// <typeparam name="TResult">Specifies the type of data contained in the 
    /// task.</typeparam>
    /// <param name="task">The task.</param>
    /// <param name="timeout">The timeout.</param>
    /// <returns>The new Task that may time out.</returns>
    public static Task<TResult> WithTimeout<TResult>(this Task<TResult> task, 
                                                          TimeSpan timeout)
    {
        var result = new TaskCompletionSource<TResult>(task.AsyncState);
        var timer = new Timer(state => 
                        ((TaskCompletionSource<TResult>)state).TrySetCanceled(),
                        result, timeout, TimeSpan.FromMilliseconds(-1));
        task.ContinueWith(t =>
        {
            timer.Dispose();
            result.TrySetFromTask(t);
        }, TaskContinuationOptions.ExecuteSynchronously);
        return result.Task;
    }

您可以创建任务后立即使用它:

You can use it right after creating your task:

var myTask=Task.Factory.StartNew(()=>{...})
           .WithTimeout(TimeSpan.FromSeconds(20));

在一般情况下,您可以创建通过创建一个TaskCompletionSource调用它的setResult,在SetCancelled方法你想要的行为应对您所设定的事件或标准。

In general, you can create the behaviour you want by creating a TaskCompletionSource calling its SetResult, SetCancelled methods in response to the events or criteria you set.

这篇关于的CancellationToken和CancellationTokenSource,如何使用它?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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